"neutronvpn:createL3VPN" fails to create L3VPN for IPv6 use case. 19/88019/19
authorSurendar Raju <surendar.raju@ericsson.com>
Mon, 24 Feb 2020 07:59:58 +0000 (13:29 +0530)
committerKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Fri, 6 Mar 2020 02:59:23 +0000 (02:59 +0000)
a) Issue: vpnTargets (route-distinguisher/iRT/eRT)
are VPN properties, but according to the VPNInstance
IETF yang model, VpnTargets reside within IP-families
(v4/v6). For Boron based release, only IPv4 family was
supported and thus, making use of ipv4-family ->
vpnTargets sufficed. For R7, this will not work as at
the time of VPNInstance creation, there is no knowledge
of whether v4 or v6 family subnets will be associated
to VPN. Thus, there is no clear model to store vpnTargets.

b) Manifestation in TRs:  HX53527 - [NFVi] EO request
for "neutronvpn:createL3VPN" fails to create L3VPN:
Pure IPv6 VPNs fail to get VPN connectivity due to
the above anomaly.

c) Solution: Move vpnTargets and RD out of IP-family
containers. Representation of the new yang-model is as below:
container vpn-instances {
list vpn-instance {
list vpnTargets { }
Ipv4-family {
}
Ipv6-family {
}

}
}
}

d) Additional changes:
1. For use-cases where IPv4 family is being
incorrectly used and functionality is working per chance
need to align with the new model.
2. Refactoring to remove ipv4-family
and ipv6-family from yang model itself in case
we are not using these at all.

e) Benefits:
1. Functional benefits to avoid storing data
inconsistently, and moving towards making our models more logical
2. Refactoring will lead to cleaner code.
3. Removing large config containers of ipv4-family
and ipv6 family will lead to performance improvements.

Change-Id: Id33d4931f994f739d31620f8bdc492f15cf8ffd1
Signed-off-by: Surendar Raju <surendar.raju@ericsson.com>
18 files changed:
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatUtil.java
neutronvpn/api/src/main/yang/l3vpn-instances-interfaces.yang
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronBgpvpnChangeListener.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronSubnetChangeListener.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManager.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnUtils.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/evpn/manager/NeutronEvpnManager.java
vpnmanager/api/src/main/java/org/opendaylight/netvirt/vpnmanager/api/IVpnManager.java
vpnmanager/api/src/main/yang/odl-l3vpn.yang
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/SubnetmapChangeListener.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInstanceListener.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnManagerImpl.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnOpStatusListener.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnUtil.java
vpnmanager/impl/src/test/java/org/opendaylight/netvirt/vpnmanager/intervpnlink/L3VpnTestCatalog.java
vpnmanager/impl/src/test/java/org/opendaylight/netvirt/vpnmanager/test/VpnServiceTest.java
vpnmanager/impl/src/test/java/org/opendaylight/netvirt/vpnmanager/test/VpnSubnetRouteHandlerTest.java
vpnmanager/shell/src/main/java/org/opendaylight/netvirt/vpnmanager/shell/ShowVpn.java

index ac6ddcf04582dfb5cc5f7d02d609d29d9b74f542..5d99bb22fd75ff459732619e6a0640a579f1be89 100644 (file)
@@ -231,7 +231,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.IpPortKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.snatint.ip.port.map.intip.port.map.ip.port.IntIpProtoTypeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnAfConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
@@ -2131,9 +2130,8 @@ public final class NatUtil {
 
     @NonNull
     public static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
-        VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
-        return vpnConfig.getRouteDistinguisher() != null ? new ArrayList<>(
-                vpnConfig.getRouteDistinguisher()) : new ArrayList<>();
+        return vpnInstance.getRouteDistinguisher() != null ? new ArrayList<>(
+                vpnInstance.getRouteDistinguisher()) : new ArrayList<>();
     }
 
     public static String validateAndAddNetworkMask(String ipAddress) {
index 8d7e21ab4e25ebd3c1c1a71da9319ba2ebb67503..b39762263267647723ccdddf36ff8240ed51aeb7 100644 (file)
@@ -20,509 +20,156 @@ module l3vpn-instances-interfaces {
             This has been adapted from l3vpn.yang";
     }
 
-    grouping vpn-af-config {
-        description "A set of configuration parameters that is applicable to both IPv4 and
-            IPv6 address family for a VPN instance .";
+    /*
+     * VPN instance view.
+     */
+    container vpn-instances {
+       list vpn-instance {
+          max-elements "unbounded";
+          min-elements "0";
+          key "vpn-instance-name";
+
+          leaf vpn-instance-name {
+             mandatory "true";
+             type string;
+             description
+                "The name of the vpn-instance.";
+          }
+
+          leaf-list route-distinguisher {
 
-        leaf-list route-distinguisher {
-            description "The route-distinguisher command configures a route distinguisher (RD)
-                for the IPv4 or IPv6 address family of a VPN instance. Format is ASN:nn or IP-address:nn.";
+             description
+             "A set of configuration parameters that is applicable to both IPv4 and
+             IPv6 address family for a VPN instance.
 
-            config "true";
-            type string {
+             Format is ASN:nn or IP-address:nn.";
+
+             config "true";
+             type string {
                 length "3..21";
-            }
-        }
+             }
+          }
 
-        container vpnTargets {
-            description "The vpn-target command configures the export or import VPN target
-                extended community attribute for the VPN instance IPv4/IPv6 address family.
+          container vpnTargets {
+
+             description
+                "The vpn-target command configures the export or import VPN target
+                extended community attribute for the VPN instance IPv4/IPv6 address
+                family.
                 Format is ASN:nn or IP-address:nn.";
 
-            list vpnTarget {
+             list vpnTarget {
                 key "vrfRTValue";
                 max-elements "unbounded";
                 min-elements "0";
-                description "L3vpn vpntarget configure class";
+
+                description
+                   "L3vpn vpntarget configure class";
 
                 leaf vrfRTValue {
 
-                    description "Vpn-target: adds VPN target extended community attribute to the
-                        export or import VPN target extended community list. The
-                        vpn-target can be expressed in either of the following formats:
-                        (1)16-bit AS number:32-bit user-defined number
-                          For example, 1:3. The AS number ranges from 0 to 65535. The
-                          user-defined number ranges from 0 to 4294967295. The AS number
-                          and the user-defined number cannot be 0s at the same time.
-                          That is, a VPN target cannot be 0:0.
-                       (2)32-bit IP address:16-bit user-defined number
-                          For example, 192.168.122.15:1. The IP address ranges from
-                          0.0.0.0 to 255.255.255.255. The user-defined number ranges from 0 to 65535.
-                       (3)32-bit IP address:16-bit user-defined number
-                          For example, 192.168.122.15:1. An IP address ranges from
-                          0.0.0.0 to 255.255.255.255. A user-defined number ranges from 0 to 65535.";
-
-                    config "true";
-                    mandatory "true";
-                    type string {
-                        length "3..21";
-                    }
+                   description
+                      "Vpn-target: adds VPN target extended community attribute to the
+                      export or import VPN target extended community list. The
+                      vpn-target can be expressed in either of the following formats:
+                      (1)16-bit AS number:32-bit user-defined number
+                      For example, 1:3. The AS number ranges from 0 to 65535. The
+                      user-defined number ranges from 0 to 4294967295. The AS number
+                      and the user-defined number cannot be 0s at the same time.
+                      That is, a VPN target cannot be 0:0.
+                      (2)32-bit IP address:16-bit user-defined number
+                      For example, 192.168.122.15:1. The IP address ranges from
+                      0.0.0.0 to 255.255.255.255. The user-defined number ranges from
+                      0 to 65535.
+                      (3)32-bit IP address:16-bit user-defined number
+                      For example, 192.168.122.15:1. An IP address ranges from
+                      0.0.0.0 to 255.255.255.255. A user-defined number ranges from 0
+                      to 65535.";
+
+                   config "true";
+                   mandatory "true";
+                   type string {
+                      length "3..21";
+                   }
                 }
 
                 leaf vrfRTType {
-                    description "Specifies the vpn target type, export-extcommunity:
-                        specifies the extended community attributes carried in routing
-                        information to be sent. import-extcommunity: receives routing
-                        information carrying specified extended community attributes.";
-
-                    mandatory "true";
-                    type enumeration {
-                        enum export_extcommunity {
-                            value "0";
-                            description "export-extcommunity:";
-                        }
-                        enum import_extcommunity {
-                            value "1";
-                            description "import-extcommunity:";
-                        }
-                        enum both {
-                            value "2";
-                            description "export-extcommunity & import-extcommunity:";
-                        }
-                    }
-                }
-            }
-        }
-
-        container apply-label {
-            description "Apply one label mode for the VPN instance route.";
-
-            choice apply-label-mode {
-                case per-route {
-                    description "The apply-label per-route command enables the one-label-per-route
-                        mode. The VPN instance IPv4/IPv6 address family assigns a unique
-                        label to each route to be sent to the peer PE.";
-
-                    leaf apply-label-per-route {
-                        type boolean;
-                        default "true";
-                    }
-                }
-                case per-instance {
-                    description "The apply-label per-instance command applies one label to all VPN
-                        instance IPv4 address family or IPv6 address family routes to a peer PE.";
-
-                    leaf apply-label-per-instance {
-                        type boolean;
-                        default "false";
-                    }
-                }
-            }
-        }//End of "container apply-label"
-
-        leaf import-route-policy {
-            description "The import route-policy command associates a VPN instance enabled
-                with the IPv4 or IPv6 address family with an import routing policy.
-                Only one import routing policy can be associated with a VPN instance
-                enabled with the IPv4 or IPv6 address family. If the import route-policy
-                command is run more than once, the latest configuration overrides the previous ones.";
-
-            config "true";
-            type string {
-                length "1..40";
-            }
-        }
-
-        leaf export-route-policy {
-            description "The export route-policy command associates a VPN instance enabled
-                with the IPv4 or IPv6 address family with an export routing policy.
-                Only one export routing policy can be associated with a VPN instance enabled with
-                the IPv4 or IPv6 address family. If the export route-policy command is run more than once,
-                the latest configuration overrides the previous ones.";
-
-            config "true";
-            type string {
-                length "1..40";
-            }
-        }
-
-        container prefix-limit {
-            description "The prefix limit command sets a limit on the maximum number of
-                prefixes supported in the existing VPN instance, preventing the
-                PE from importing excessive VPN route prefixes.";
 
-            leaf prefix-limit-number {
-                description "Specifies the maximum number of prefixes supported in the VPN
-                    instance IPv4 or IPv6 address family.";
-
-                type uint32 {
-                    range "1..4294967295";
+                   description
+                      "Specifies the vpn target type, export-extcommunity:
+                      specifies the extended community attributes carried in routing
+                      information to be sent. import-extcommunity: receives routing
+                      information carrying specified extended community attributes.";
+
+                   mandatory "true";
+                   type enumeration {
+                      enum export_extcommunity {
+                         value "0";
+                         description "export-extcommunity:";
+                      }
+                      enum import_extcommunity {
+                         value "1";
+                         description "import-extcommunity:";
+                      }
+                      enum both {
+                         value "2";
+                         description "export-extcommunity & import-extcommunity:";
+                      }
+                   }
                 }
-            }
-
-            choice prefix-limit-action {
-                case enable-alert-percent {
-                    leaf alert-percent-value {
-                        description "Specifies the proportion of the alarm threshold to the maximum
-                            number of prefixes.";
-                        type uint8 {
-                            range "1..100";
-                        }
-                    }
-                    leaf route-unchanged {
-                        description "Indicates that the routing table remains unchanged. By default,
-                            route-unchanged is not configured. When the number of prefixes
-                            in the routing table is greater than the value of the parameter number,
-                            routes are processed as follows:
-                             (1)If route-unchanged is configured, routes in the routing table remain unchanged.
-                             (2)If route-unchanged is not configured, all routes in the
-                                routing table are deleted and then re-added.";
-
-                        config "true";
-                        type boolean;
-                        default "false";
-                    }
+             }
+          }
+
+          leaf l2vpn {
+             type boolean;
+             default false;
+             description
+                "The type of the VPN Instance.
+                false indicates it is an L3VPN.
+                true indicates it is an EVPN";
+          }
+
+          leaf bgpvpn-type {
+             type enumeration {
+                enum InternetBGPVPN {
+                   value "0";
+                   description "Internet BGPVPN";
                 }
-                case enable-simple-alert {
-                    leaf simple-alert {
-                        description "Indicates that when the number of VPN route prefixes exceeds
-                        number, prefixes can still join the VPN routing table and alarms are displayed.";
-
-                        config "true";
-                        type boolean;
-                        default "false";
-                    }
+                enum BGPVPN {
+                   value "1";
+                   description "BGPVPN";
                 }
-            }
-        }
-
-        container routing-table-limit {
-            description "The routing-table limit command sets a limit on the maximum number of
-                routes that the IPv4 or IPv6 address family of a VPN instance can support.
-                By default, there is no limit on the maximum number of routes that the
-                IPv4 or IPv6 address family of a VPN instance can support, but the
-                total number of private network and public network routes on a device
-                cannot exceed the allowed maximum number of unicast routes.";
-
-            leaf routing-table-limit-number {
-                description "Specifies the maximum number of routes supported by a VPN instance. ";
-                config "true";
-                type uint32 {
-                    range "1..4294967295";
+                enum InternalVPN {
+                   value "2";
+                   description "InternalVPN";
                 }
-            }
-            choice routing-table-limit-action {
-                case enable-alert-percent {
-                    leaf alert-percent-value {
-                        description "Specifies the percentage of the maximum number of routes. When
-                            the maximum number of routes that join the VPN instance is up
-                            to the value (number*alert-percent)/100, the system prompts alarms.
-                            The VPN routes can be still added to the routing table,
-                            but after the number of routes reaches number, the subsequent routes are dropped.";
-
-                        config "true";
-                        type uint8 {
-                            range "1..100";
-                        }
-                    }
+             }
+             default BGPVPN;
+          }
+
+          leaf ip-address-family-configured {
+             type enumeration {
+                enum "undefined" {
+                   value "0";
                 }
-                case enable-simple-alert {
-                    leaf simple-alert {
-                        description "Indicates that when VPN routes exceed number, routes can still
-                            be added into the routing table, but the system prompts alarms.
-                            However, after the total number of VPN routes and network public
-                            routes reaches the unicast route limit specified in the License,
-                            the subsequent VPN routes are dropped.";
-                        config "true";
-                        type boolean;
-                    }
+                enum "ipv4" {
+                   value "4";
                 }
-            }
-        }
-
-        leaf vpn-frr {
-            description "Enable VPN FRR in the VPN instance address family view.
-                If a PE is connected to two other PEs, running the vpn frr command in
-                the VPN instance address family view of the PE enables VPN FRR and
-                improves network reliability. After VPN FRR is configured, traffic can
-                switch to the secondary LSP immediately after the primary LSP becomes faulty.";
-
-            type boolean;
-            default "false";
-        }
-
-
-        /*
-        * VPN QoS.
-        */
-        container l3vpnVrfPipe {
-            description "The diffserv-mode command configures the mode of the MPLS
-                differentiated service (Diff-Serv) for ensuring end-to-end QoS.";
-
-            leaf pipeMode {
-                description "Pipe mode";
-
-                type enumeration {
-                    enum pipe {
-                        value "0";
-                            description "pipe: Indicates that the Pipe MPLS Diff-Serv mode is adopted.";
-                    }
-                    enum shortPipe {
-                        value "1";
-                        description "shortPipe: Indicates that the Short-pipe MPLS Diff-Serv mode is adopted.";
-                    }
-                    enum uniform {
-                        value "2";
-                        description "uniform: Indicates that the Uniform MPLS Diff-Serv mode is adopted.";
-                    }
+                enum "ipv6" {
+                   value "6";
                 }
-                default "uniform";
-            }
-
-            leaf serviceClass {
-                description "Service Class, Specifies the service type when the packet enters the
-                    public network from the private network. The values are cs7, cs6, ef, af4, af3, af2, af1, be.";
-
-                type enumeration {
-                    enum be {
-                        value "0";
-                        description "be:";
-                    }
-                    enum af1 {
-                        value "1";
-                        description "af1:";
-                    }
-                    enum af2 {
-                        value "2";
-                        description "af2:";
-                    }
-                    enum af3 {
-                        value "3";
-                        description "af3:";
-                    }
-                    enum af4 {
-                        value "4";
-                        description "af4:";
-                    }
-                    enum ef {
-                        value "5";
-                        description "ef:";
-                    }
-                    enum cs6 {
-                        value "6";
-                        description "cs6:";
-                    }
-                    enum cs7 {
-                        value "7";
-                        description "cs7:";
-                    }
+                enum "ipv4-and-ipv6" {
+                   value "10";
                 }
-                default "be";
-            }
+             }
+             default "undefined";
+          }
 
-            leaf color {
-                description "Specifies a color for marking the discard priority of a packet
-                    transferred from a private network to a public network. The values
-                    are green, yellow, and red.";
+          leaf l3vni {
+             type uint32;
+          }
 
-                type enumeration {
-                    enum green {
-                        value "0";
-                        description "green:";
-                    }
-                    enum yellow {
-                        value "1";
-                        description "yellow:";
-                    }
-                    enum red {
-                        value "2";
-                        description "red:";
-                    }
-                }
-                default "green";
-            }
-
-            leaf dsName {
-                description "Specifies the DS domain name of the specified Per-Hop Behavior (PHB)
-                    applied to the egress in Short pipe mode. It is a string of 1 to 31 characters.";
-
-                type string;
-                default "default";
-            }
-        }
-
-        container l3vpnTtlMode {
-            description "The ttl-mode command enables MPLS to process the TTL in a specified
-                mode. By default, MPLS processes the TTL in pipe mode.";
-
-            leaf ttlMode {
-                description "TTL mode";
-                default "pipe";
-                type enumeration {
-                    enum pipe {
-                        value "0";
-                        description "pipe: Enables MPLS to process the TTL in pipe mode.";
-                    }
-
-                    enum uniform {
-                        value "1";
-                        description "uniform: Enables MPLS to process the TTL in uniform mode.";
-                    }
-                }
-            }
-        }
-
-        leaf tunnel-policy {
-            description "The tnl-policy command associates the IPv4 or IPv6 address family of
-                a VPN instance with a tunnel policy.";
-
-            type string {
-                length "1..39";
-            }
-        }
-
-        container importRibs {
-            description "Import route class";
-
-            leaf protocol {
-                description "Specifies the protocol from which routes are imported.
-                    At present, In the IPv4 unicast address family view, the protocol
-                    can be IS-IS,static, direct and BGP.";
-
-                type enumeration {
-                    enum ALL {
-                        value "0";
-                        description "ALL:";
-                    }
-                    enum Direct {
-                        value "1";
-                        description "Direct:";
-                    }
-                    enum OSPF {
-                        value "2";
-                        description "OSPF:";
-                    }
-                    enum ISIS {
-                        value "3";
-                        description "ISIS:";
-                    }
-                    enum Static {
-                        value "4";
-                        description "Static:";
-                    }
-                    enum RIP {
-                        value "5";
-                        description "RIP:";
-                    }
-                    enum BGP {
-                        value "6";
-                        description "BGP:";
-                    }
-                    enum OSPFV3 {
-                        value "7";
-                        description "OSPFV3:";
-                    }
-                    enum RIPNG {
-                        value "8";
-                        description "RIPNG:";
-                    }
-                    enum INVALID {
-                        value "9";
-                        description "INVALID:";
-                    }
-                }
-            }
-
-            leaf processId {
-                description "Specifies the process ID if the protocol from routes are imported is IS-IS.";
-
-                default "0";
-                type uint32 {
-                    range "0..4294967295";
-                }
-            }
-
-            leaf bgp-valid-route {
-                type boolean;
-            }
-
-            leaf policyName {
-                description "Policy Id for import routes";
-                type string {}
-            }
-        }
-
-        leaf traffic-statistics {
-            description "The traffic-statistics enable command enables traffic statistics
-                for a VPN instance.";
-
-            type boolean;
-            default "false";
-        }
-    }
-
-
-    /*
-     * VPN instance view.
-     */
-    container vpn-instances {
-        description "VPN instances configuration parameters. VPN instances support both the
-            IPv4 and IPv6 address families.";
-
-        list vpn-instance {
-            max-elements "unbounded";
-            min-elements "0";
-            key "vpn-instance-name";
-            description "Specifies the name of the VPN instance. It is a string of 1 to 31
-                case-sensitive characters.";
-
-            leaf vpn-instance-name {
-                mandatory "true";
-                type string;
-                description "The name of the vpn-instance.";
-            }
-            leaf type {
-                description "The type of the VPN Instance.
-                L3 indicates it is an L3VPN.
-                L2 indicates it is an EVPN";
-
-                type enumeration {
-                    enum l3 {
-                        value "0";
-                        description "L3VPN";
-                    }
-                    enum l2 {
-                        value "1";
-                        description "EVPN";
-                    }
-                }
-                default "l3";
-            }
-
-            leaf l3vni {
-                type uint32;
-            }
-
-            leaf description {
-                description "A textual description of VPN instance, the VPN instance description
-                    helps users memorize the VPN instance.";
-
-                type string {
-                    length "1..242";
-                    pattern "([^?]*)";
-                }
-            }
-
-            container ipv4-family {
-                description "The IPv4 address family is enabled for the VPN instance.";
-                uses vpn-af-config;
-            }
-
-            container ipv6-family {
-                description "The IPv6 address family is enabled for the VPN instance.";
-                uses vpn-af-config;
-            }
-        }
+       }
     }
 
     augment "/vpn-interfaces/vpn-interface" {
index bd3a9d4798cca1570d0f309f6f05864ef1adb63a..32322245c360d94a85bcba5762c049a52fe37b8b 100644 (file)
@@ -29,7 +29,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.bgpvpns.rev150903.BgpvpnTypeBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.bgpvpns.rev150903.BgpvpnTypeL3;
@@ -99,7 +98,6 @@ public class NeutronBgpvpnChangeListener extends AsyncDataTreeChangeListenerBase
         LOG.trace("Adding Bgpvpn : key: {}, value={}", identifier, input);
         String vpnName = input.getUuid().getValue();
         if (isBgpvpnTypeL3(input.getType())) {
-            VpnInstance.Type vpnInstanceType = VpnInstance.Type.L3;
             // handle route-target(s)
             List<String> inputRouteList = input.getRouteTargets();
             List<String> inputImportRouteList = input.getImportTargets();
@@ -160,7 +158,7 @@ public class NeutronBgpvpnChangeListener extends AsyncDataTreeChangeListenerBase
                     try {
                         nvpnManager.createVpn(input.getUuid(), input.getName(), input.getTenantId(), rd,
                                 importRouteTargets, exportRouteTargets, routersList, networkList,
-                                vpnInstanceType, 0 /*l3vni*/);
+                                false /*isL2Vpn*/, 0 /*l3vni*/);
                     } catch (Exception e) {
                         LOG.error("Creation of BGPVPN {} failed", vpnName, e);
                     }
index 90db28e0d6008b0a2a9a64ca170ff1ac9ce49ef6..913e0a7ed068af97f3def7f3dc863c1fb0ff621f 100644 (file)
@@ -23,7 +23,7 @@ import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTarget;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTarget;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapBuilder;
index 2eecb958fa29feb232c8f3e0040aaeff8b653c44..688438e8e8554d8259595d0da54cce0014b1a4c3 100644 (file)
@@ -87,16 +87,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.re
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.Adjacency.AdjacencyType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.AdjacencyBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.AdjacencyKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.VpnTargets;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.VpnTargetsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTarget;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTargetBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTargetKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.Ipv6FamilyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.VpnTargets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.VpnTargetsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTarget;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTargetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTargetKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterfaceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterfaceKey;
@@ -546,29 +544,25 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                     SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
                             vpnIdentifier);
             if (!vpnInstanceConfig.isPresent()) {
-                LOG.debug("No VpnInstance present under config vpnInstance:{}", vpnInstanceId);
+                LOG.debug("updateVpnInstanceWithRDs: "
+                        + "No VpnInstance present under config vpnInstance:{}", vpnInstanceId);
                 return;
             }
             VpnInstance vpnInstance = vpnInstanceConfig.get();
             VpnInstanceBuilder updateVpnInstanceBuilder = new VpnInstanceBuilder(vpnInstance);
-            if (vpnInstance.getIpv4Family() != null) {
-                Ipv4FamilyBuilder ipv4FamilyBuilder = new Ipv4FamilyBuilder(vpnInstance.getIpv4Family());
-                updateVpnInstanceBuilder.setIpv4Family(ipv4FamilyBuilder.setRouteDistinguisher(rds).build());
-            }
-            if (vpnInstance.getIpv6Family() != null) {
-                Ipv6FamilyBuilder ipv6FamilyBuilder = new Ipv6FamilyBuilder(vpnInstance.getIpv6Family());
-                updateVpnInstanceBuilder.setIpv6Family(ipv6FamilyBuilder.setRouteDistinguisher(rds).build());
-            }
-            LOG.debug("Updating Config vpn-instance: {} with the list of RDs: {}", vpnInstanceId, rds);
+            updateVpnInstanceBuilder.setRouteDistinguisher(rds);
+            LOG.debug("updateVpnInstanceWithRDs: "
+                    + "Updating Config vpn-instance: {} with the list of RDs: {}", vpnInstanceId, rds);
             SingleTransactionDataBroker.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, vpnIdentifier,
                     updateVpnInstanceBuilder.build());
         } catch (ReadFailedException | TransactionCommitFailedException ex) {
-            LOG.warn("Error configuring feature ", ex);
+            LOG.warn("updateVpnInstanceWithRDs: Error configuring vpn-instance: {} with "
+                    + "the list of RDs: {}", vpnInstanceId, rds, ex);
         }
     }
 
     private void updateVpnInstanceNode(Uuid vpnId, List<String> rd, List<String> irt, List<String> ert,
-                                       VpnInstance.Type type, long l3vni, IpVersionChoice ipVersion) {
+                                       boolean isL2Vpn, long l3vni, IpVersionChoice ipVersion) {
         String vpnName = vpnId.getValue();
         VpnInstanceBuilder builder = null;
         List<VpnTarget> vpnTargetList = new ArrayList<>();
@@ -589,7 +583,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
             LOG.debug("updating existing vpninstance node");
         } else {
             builder = new VpnInstanceBuilder().withKey(new VpnInstanceKey(vpnName)).setVpnInstanceName(vpnName)
-                    .setType(type).setL3vni(l3vni);
+                    .setL2vpn(isL2Vpn).setL3vni(l3vni);
         }
         if (irt != null && !irt.isEmpty()) {
             if (ert != null && !ert.isEmpty()) {
@@ -623,25 +617,12 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         }
 
         VpnTargets vpnTargets = new VpnTargetsBuilder().setVpnTarget(vpnTargetList).build();
-        Ipv4FamilyBuilder ipv4vpnBuilder = new Ipv4FamilyBuilder().setVpnTargets(vpnTargets);
-        Ipv6FamilyBuilder ipv6vpnBuilder = new Ipv6FamilyBuilder().setVpnTargets(vpnTargets);
-
         if (rd != null && !rd.isEmpty()) {
-            ipv4vpnBuilder.setRouteDistinguisher(rd);
-            ipv6vpnBuilder.setRouteDistinguisher(rd);
+            builder.setRouteDistinguisher(rd).setVpnTargets(vpnTargets);
         }
 
-        if (ipVersion != null && ipVersion.isIpVersionChosen(IpVersionChoice.IPV4)) {
-            builder.setIpv4Family(ipv4vpnBuilder.build());
-        }
-        if (ipVersion != null && ipVersion.isIpVersionChosen(IpVersionChoice.IPV6)) {
-            builder.setIpv6Family(ipv6vpnBuilder.build());
-        }
-        if (ipVersion != null && ipVersion.isIpVersionChosen(IpVersionChoice.UNDEFINED)) {
-            builder.setIpv4Family(ipv4vpnBuilder.build());
-        }
+        builder.setIpAddressFamilyConfigured(VpnInstance.IpAddressFamilyConfigured.forValue(ipVersion.choice));
         VpnInstance newVpn = builder.build();
-
         try (AcquireResult lock = tryVpnLock(vpnId)) {
             if (!lock.wasAcquired()) {
                 // FIXME: why do we even bother with locking if we do not honor it?!
@@ -1197,7 +1178,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
         IpVersionChoice ipVersChoices = neutronvpnUtils.getIpVersionChoicesFromRouterUuid(routerId);
 
         // Update VPN Instance node
-        updateVpnInstanceNode(vpnId, rdList, irtList, ertList, VpnInstance.Type.L3, 0 /*l3vni*/, ipVersChoices);
+        updateVpnInstanceNode(vpnId, rdList, irtList, ertList, false /*isL2Vpn*/, 0 /*l3vni*/, ipVersChoices);
 
         // Update local vpn-subnet DS
         updateVpnMaps(vpnId, name, routerId, tenantId, networksList);
@@ -1231,13 +1212,13 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
      * @param ertList A list of Export Route Targets
      * @param routerIdsList ist of neutron router Id to associate with created VPN
      * @param networkList UUID of the neutron network the VPN may be associated to
-     * @param type Type of the VPN Instance
+     * @param isL2Vpn True if VPN Instance is of type L2, false if L3
      * @param l3vni L3VNI for the VPN Instance using VxLAN as the underlay
      * @throws Exception if association of L3VPN failed
      */
     public void createVpn(Uuid vpnId, String name, Uuid tenantId, List<String> rdList, List<String> irtList,
                     List<String> ertList,  @Nullable List<Uuid> routerIdsList, @Nullable List<Uuid> networkList,
-                    VpnInstance.Type type, long l3vni) throws Exception {
+                          boolean isL2Vpn, long l3vni) throws Exception {
 
         IpVersionChoice ipVersChoices = IpVersionChoice.UNDEFINED;
 
@@ -1247,7 +1228,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 ipVersChoices = ipVersChoices.addVersion(vers);
             }
         }
-        updateVpnInstanceNode(vpnId, rdList, irtList, ertList, type, l3vni, ipVersChoices);
+        updateVpnInstanceNode(vpnId, rdList, irtList, ertList, isL2Vpn, l3vni, ipVersChoices);
 
         // Please note that router and networks will be filled into VPNMaps
         // by subsequent calls here to associateRouterToVpn and
@@ -1307,7 +1288,6 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 warningcount++;
                 continue;
             }
-            VpnInstance.Type vpnInstanceType = VpnInstance.Type.L3;
             long l3vni = 0;
             if (vpn.getL3vni() != null) {
                 l3vni = vpn.getL3vni().toJava();
@@ -1402,7 +1382,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                         ? new ArrayList<>(vpn.getExportRT()) : new ArrayList<>();
 
                 createVpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), rdList,
-                        importRdList, exportRdList, rtrIdsList, vpn.getNetworkIds(), vpnInstanceType, l3vni);
+                        importRdList, exportRdList, rtrIdsList, vpn.getNetworkIds(), false /*isL2Vpn*/, l3vni);
             } catch (Exception ex) {
                 LOG.error("VPN Creation exception :", ex);
                 errorList.add(RpcResultBuilder.newError(ErrorType.APPLICATION,
@@ -1455,10 +1435,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                     for (VpnInstance vpn : optionalVpns.get().nonnullVpnInstance()) {
                         // eliminating implicitly created (router and VLAN provider external network specific) VPNs
                         // from getL3VPN output
-                        if (vpn.getIpv4Family().getRouteDistinguisher() != null) {
-                            vpns.add(vpn);
-                        }
-                        if (vpn.getIpv6Family().getRouteDistinguisher() != null) {
+                        if (vpn.getRouteDistinguisher() != null) {
                             vpns.add(vpn);
                         }
                     }
@@ -1478,8 +1455,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                                 vpnIdentifier);
                 // eliminating implicitly created (router or VLAN provider external network specific) VPN from
                 // getL3VPN output
-                if (optionalVpn.isPresent() && (optionalVpn.get().getIpv4Family().getRouteDistinguisher() != null
-                        || optionalVpn.get().getIpv6Family().getRouteDistinguisher() != null)) {
+                if (optionalVpn.isPresent() && optionalVpn.get().getRouteDistinguisher() != null) {
                     vpns.add(optionalVpn.get());
                 } else {
                     result.set(
@@ -1493,21 +1469,16 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 // create VpnMaps id
                 L3vpnInstancesBuilder l3vpn = new L3vpnInstancesBuilder();
                 List<String> rd = Collections.EMPTY_LIST;
-                if (vpnInstance.getIpv4Family().getRouteDistinguisher() != null) {
-                    rd = vpnInstance.getIpv4Family().getRouteDistinguisher();
-                } else if (vpnInstance.getIpv6Family().getRouteDistinguisher() != null) {
-                    rd = vpnInstance.getIpv6Family().getRouteDistinguisher();
+                if (vpnInstance.getRouteDistinguisher() != null) {
+                    rd = vpnInstance.getRouteDistinguisher();
                 }
                 List<String> ertList = new ArrayList<>();
                 List<String> irtList = new ArrayList<>();
 
-                if (vpnInstance.getIpv4Family().getVpnTargets() != null
-                        || vpnInstance.getIpv6Family().getVpnTargets() != null) {
+                if (vpnInstance.getVpnTargets() != null) {
                     List<VpnTarget> vpnTargetList = Collections.EMPTY_LIST;
-                    if (!vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget().isEmpty()) {
-                        vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
-                    } else if (!vpnInstance.getIpv6Family().getVpnTargets().getVpnTarget().isEmpty()) {
-                        vpnTargetList = vpnInstance.getIpv6Family().getVpnTargets().getVpnTarget();
+                    if (!vpnInstance.getVpnTargets().getVpnTarget().isEmpty()) {
+                        vpnTargetList = vpnInstance.getVpnTargets().getVpnTarget();
                     }
                     if (!vpnTargetList.isEmpty()) {
                         for (VpnTarget vpnTarget : vpnTargetList) {
@@ -2199,21 +2170,14 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
                 nextHopList.add(routeTmp.getNexthop().stringValue());
             }
             final List<String> rdList = new ArrayList<>();
-            if (vpnInstance.getIpv4Family() != null
-                    && vpnInstance.getIpv4Family().getRouteDistinguisher() != null) {
-                vpnInstance.getIpv4Family().getRouteDistinguisher().forEach(rd -> {
+            if (vpnInstance != null
+                    && vpnInstance.getRouteDistinguisher() != null) {
+                vpnInstance.getRouteDistinguisher().forEach(rd -> {
                     if (rd != null) {
                         rdList.add(rd);
                     }
                 });
             }
-            if (vpnInstance.getIpv6Family() != null && vpnInstance.getIpv6Family().getRouteDistinguisher() != null) {
-                vpnInstance.getIpv6Family().getRouteDistinguisher().forEach(rd -> {
-                    if (rd != null && !rdList.contains(rd)) {
-                        rdList.add(rd);
-                    }
-                });
-            }
             // 1. VPN Instance Name
             String typeAlarm = "for vpnId: " + vpnId + " have exceeded next hops for prefixe";
 
@@ -2359,7 +2323,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even
     }
 
     private boolean isVpnOfTypeL2(VpnInstance vpnInstance) {
-        return vpnInstance != null && vpnInstance.getType() == VpnInstance.Type.L2;
+        return vpnInstance != null && vpnInstance.isL2vpn();
     }
 
     // TODO Clean up the exception handling
index 5c43ac436f7db9b58d2e6dca3726188c548901fc..9ccdd3d85b13e009ed979118ed857016f1fb37e9 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netvirt.neutronvpn;
 
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
 
 import com.google.common.base.Function;
@@ -108,6 +109,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.interfaces.VpnInterfaceKey;
@@ -1220,10 +1222,7 @@ public class NeutronvpnUtils {
         Optional<VpnInstances> vpnInstancesOptional = read(LogicalDatastoreType.CONFIGURATION, path);
         if (vpnInstancesOptional.isPresent() && vpnInstancesOptional.get().getVpnInstance() != null) {
             for (VpnInstance vpnInstance : vpnInstancesOptional.get().getVpnInstance()) {
-                if (vpnInstance.getIpv4Family() == null) {
-                    continue;
-                }
-                List<String> rds = vpnInstance.getIpv4Family().getRouteDistinguisher();
+                List<String> rds = vpnInstance.getRouteDistinguisher();
                 if (rds != null) {
                     existingRDs.addAll(rds);
                 }
@@ -1462,13 +1461,13 @@ public class NeutronvpnUtils {
 
     public void updateVpnInstanceWithIpFamily(String vpnName, IpVersionChoice ipVersion, boolean add) {
         jobCoordinator.enqueueJob("VPN-" + vpnName, () -> {
-            VpnInstanceOpDataEntry vpnInstanceOpDataEntry = getVpnInstanceOpDataEntryFromVpnId(vpnName);
-            if (vpnInstanceOpDataEntry == null) {
+            VpnInstance vpnInstance = getVpnInstance(dataBroker, new Uuid(vpnName));
+            if (vpnInstance == null) {
                 return Collections.emptyList();
             }
-            if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
+            if (vpnInstance.isL2vpn()) {
                 LOG.debug("updateVpnInstanceWithIpFamily: Update VpnInstance {} with ipFamily {}."
-                        + "VpnInstanceOpDataEntry is L2 instance. Do nothing.", vpnName, ipVersion);
+                        + "VpnInstance is L2 instance. Do nothing.", vpnName, ipVersion);
                 return Collections.emptyList();
             }
             if (ipVersion == IpVersionChoice.UNDEFINED) {
@@ -1476,24 +1475,32 @@ public class NeutronvpnUtils {
                         + "is not allowed. Do nothing", vpnName);
                 return Collections.emptyList();
             }
-            VpnInstanceOpDataEntryBuilder builder = new VpnInstanceOpDataEntryBuilder()
-                    .setVrfId(vpnInstanceOpDataEntry.getVrfId());
+            VpnInstanceBuilder builder = new VpnInstanceBuilder(vpnInstance);
             boolean ipConfigured = add;
-            if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV4AND6)) {
-                builder.setIpv4Configured(ipConfigured);
-                builder.setIpv6Configured(ipConfigured);
-            } else if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV4)) {
-                builder.setIpv4Configured(ipConfigured);
-            } else if (ipVersion.isIpVersionChosen(IpVersionChoice.IPV6)) {
-                builder.setIpv6Configured(ipConfigured);
+
+            int originalValue = vpnInstance.getIpAddressFamilyConfigured().getIntValue();
+            int updatedValue = ipVersion.choice;
+
+            if (originalValue != updatedValue) {
+                if (ipConfigured) {
+                    originalValue = originalValue == 0 ? updatedValue : updatedValue + originalValue;
+                } else {
+                    originalValue = 10 - updatedValue;
+                }
+            } else if (!ipConfigured) {
+                originalValue = 0;
             }
+
+            builder.setIpAddressFamilyConfigured(VpnInstance.IpAddressFamilyConfigured.forValue(originalValue));
+
+            InstanceIdentifier<VpnInstance> vpnIdentifier = InstanceIdentifier.builder(VpnInstances.class)
+                    .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
+            LOG.info("updateVpnInstanceWithIpFamily: Successfully {} IP family {} to Vpn {}",
+                    add == true ? "added" : "removed", ipVersion, vpnName);
             return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(
-                    OPERATIONAL, tx -> {
-                    tx.merge(getVpnOpDataIdentifier(vpnInstanceOpDataEntry.getVrfId()), builder.build(), false);
-                    LOG.info("updateVpnInstanceWithIpFamily: Successfully {} {} to Vpn {}",
-                            add == true ? "added" : "removed", ipVersion, vpnName);
-                }));
+                    CONFIGURATION, tx -> tx.merge(vpnIdentifier, builder.build(), false)));
         });
+        return;
     }
 
     /**
index f00594e1184455c3fef9e9c0ff1f91c018da6d74..afa3eb802feddad54ee27bb50cbbb3e2cc24dba7 100644 (file)
@@ -21,8 +21,8 @@ import org.opendaylight.netvirt.neutronvpn.NeutronvpnManager;
 import org.opendaylight.netvirt.neutronvpn.NeutronvpnUtils;
 import org.opendaylight.netvirt.vpnmanager.api.VpnHelper;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTarget;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTarget;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateEVPNInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateEVPNOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateEVPNOutputBuilder;
@@ -76,7 +76,6 @@ public class NeutronEvpnManager {
                                 vpn.getId().getValue())));
                 continue;
             }
-            VpnInstance.Type vpnInstanceType = VpnInstance.Type.L2;
             if (vpn.getRouteDistinguisher().size() > 1) {
                 errorList.add(RpcResultBuilder.newWarning(RpcError.ErrorType.PROTOCOL, "invalid-input",
                         formatAndLog(LOG::warn, "Creation of EVPN failed for VPN {} due to multiple RD input {}",
@@ -100,7 +99,7 @@ public class NeutronEvpnManager {
                         ? new ArrayList<>(vpn.getExportRT()) : new ArrayList<>();
                 neutronvpnManager.createVpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), rdList,
                         importRdList, exportRdList, null /*router-id*/, null /*network-id*/,
-                        vpnInstanceType, 0 /*l2vni*/);
+                        true /*isL2Vpn*/, 0 /*l2vni*/);
             } catch (Exception ex) {
                 errorList.add(RpcResultBuilder.newError(RpcError.ErrorType.APPLICATION,
                         formatAndLog(LOG::error, "Creation of EVPN failed for VPN {}", vpn.getId().getValue(), ex),
@@ -135,8 +134,8 @@ public class NeutronEvpnManager {
             vpns = VpnHelper.getAllVpnInstances(dataBroker);
             if (!vpns.isEmpty()) {
                 for (VpnInstance vpn : vpns) {
-                    if (vpn.getIpv4Family().getRouteDistinguisher() != null
-                            && vpn.getType() == VpnInstance.Type.L2) {
+                    if (vpn.getRouteDistinguisher() != null
+                            && vpn.isL2vpn()) {
                         vpns.add(vpn);
                     }
                 }
@@ -148,8 +147,8 @@ public class NeutronEvpnManager {
         } else {
             String name = inputVpnId.getValue();
             VpnInstance vpnInstance = VpnHelper.getVpnInstance(dataBroker, name);
-            if (vpnInstance != null && vpnInstance.getIpv4Family().getRouteDistinguisher() != null
-                    && vpnInstance.getType() == VpnInstance.Type.L2) {
+            if (vpnInstance != null && vpnInstance.getRouteDistinguisher() != null
+                    && vpnInstance.isL2vpn()) {
                 vpns.add(vpnInstance);
             } else {
                 result.set(RpcResultBuilder.<GetEVPNOutput>failed().withWarning(RpcError.ErrorType.PROTOCOL,
@@ -163,10 +162,10 @@ public class NeutronEvpnManager {
             InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap
                     .class, new VpnMapKey(vpnId)).build();
             EvpnInstancesBuilder evpn = new EvpnInstancesBuilder();
-            List<String> rd = vpnInstance.getIpv4Family().getRouteDistinguisher();
+            List<String> rd = vpnInstance.getRouteDistinguisher();
             List<String> ertList = new ArrayList<>();
             List<String> irtList = new ArrayList<>();
-            for (VpnTarget vpnTarget : vpnInstance.getIpv4Family().getVpnTargets().nonnullVpnTarget()) {
+            for (VpnTarget vpnTarget : vpnInstance.getVpnTargets().nonnullVpnTarget()) {
                 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
                     ertList.add(vpnTarget.getVrfRTValue());
                 }
index 3bb30833fd9f18df8ef9e3a3efaa9643bb2e6a60..82c13668f85c0c9c146548c83f2cee6c28338c15 100644 (file)
@@ -25,8 +25,8 @@ import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.Adjacency;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTarget;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTarget;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
 import org.opendaylight.yangtools.yang.common.Uint32;
index 4e7aec52b0ae7046e56adf08aada39e84cb1b33c..ef1af3baeb270a189760bdd89acd3991f44e87b2 100644 (file)
@@ -273,17 +273,22 @@ module odl-l3vpn {
                   default "active";
                }
            }
-           leaf ipv4-configured {
-              type boolean;
-              description
-                 "This VPN Instance handles IPv4 traffic";
-              default false;
-           }
-           leaf ipv6-configured {
-              type boolean;
-              description
-                 "This VPN Instance handles IPv6 traffic";
-              default false;
+           leaf ip-address-family-configured {
+              type enumeration {
+                 enum "undefined" {
+                    value "0";
+                 }
+                 enum "ipv4" {
+                    value "4";
+                 }
+                 enum "ipv6" {
+                    value "6";
+                 }
+                 enum "ipv4-and-ipv6" {
+                    value "10";
+                 }
+              }
+              default "undefined";
            }
            leaf bgpvpn-type {
               type enumeration {
index b5fcc47301549e10e9e3ebefa09b327245bb4f60..5ff2973befbbf450144229fef4707730aced1ee0 100644 (file)
@@ -28,7 +28,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTarget;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTarget;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkAttributes.NetworkType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
index ba4b4738929924678ee0b42fcd3f0c303d5a3fcf..84ceaf7dce235877d5b63f7c5b2b6dc6cc1a6f59 100644 (file)
@@ -64,11 +64,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnTargetsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTargetBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTargetKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnAfConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.VpnTargets;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTarget;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.VpnTargets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTarget;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.opendaylight.yangtools.yang.common.Uint64;
@@ -176,14 +175,14 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase<VpnInst
         VpnInstance original, VpnInstance update) {
         LOG.trace("VPN-UPDATE: update: VPN event key: {}, value: {}.", identifier, update);
         String vpnName = update.getVpnInstanceName();
-        if (original.getIpv4Family() != null && update.getIpv4Family() != null
-                && original.getIpv4Family().getRouteDistinguisher() != null
-                && update.getIpv4Family().getRouteDistinguisher() != null
-                && original.getIpv4Family().getRouteDistinguisher().size()
-                !=  update.getIpv4Family().getRouteDistinguisher().size()) {
+        if (original != null && update != null
+                && original.getRouteDistinguisher() != null
+                && update.getRouteDistinguisher() != null
+                && original.getRouteDistinguisher().size()
+                !=  update.getRouteDistinguisher().size()) {
             LOG.debug("VPN-UPDATE: VpnInstance:{} updated with new RDs: {} from old RDs: {}", vpnName,
-                    update.getIpv4Family().getRouteDistinguisher(),  original.getIpv4Family().getRouteDistinguisher());
-            vpnUtil.updateVpnInstanceWithRdList(vpnName, update.getIpv4Family().getRouteDistinguisher());
+                    update.getRouteDistinguisher(),  original.getRouteDistinguisher());
+            vpnUtil.updateVpnInstanceWithRdList(vpnName, update.getRouteDistinguisher());
         }
         vpnInterfaceManager.updateVpnInterfacesForUnProcessAdjancencies(vpnName);
     }
@@ -217,7 +216,7 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase<VpnInst
                         addVpnInstance(vpnInstance, confTx, operTx));
                 ListenableFutures.addErrorLogging(future, LOG, "{} call: error creating VPN {} rd {}",
                         LOGGING_PREFIX_ADD, vpnInstance.getVpnInstanceName(),
-                        vpnInstance.getIpv4Family().getRouteDistinguisher());
+                        vpnInstance.getRouteDistinguisher());
                 futures.add(future);
             }));
             Futures.addCallback(Futures.allAsList(futures),
@@ -241,7 +240,6 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase<VpnInst
                 addVpnInstance(value, writeConfigTxn, tx)), LOG, "Error adding VPN instance {}", value);
             return;
         }
-        VpnAfConfig config = value.getIpv4Family();
         String vpnInstanceName = value.getVpnInstanceName();
 
         Uint32 vpnId = vpnUtil.getUniqueId(VpnConstants.VPN_IDPOOL_NAME, vpnInstanceName);
@@ -293,10 +291,10 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase<VpnInst
             if (value.getL3vni() != null) {
                 builder.setL3vni(value.getL3vni());
             }
-            if (value.getType() == VpnInstance.Type.L2) {
+            if (value.isL2vpn()) {
                 builder.setType(VpnInstanceOpDataEntry.Type.L2);
             }
-            VpnTargets vpnTargets = config.getVpnTargets();
+            VpnTargets vpnTargets = value.getVpnTargets();
             if (vpnTargets != null) {
                 List<VpnTarget> vpnTargetList = vpnTargets.getVpnTarget();
                 if (vpnTargetList != null) {
@@ -314,7 +312,7 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase<VpnInst
             VpnTargetsBuilder vpnTargetsBuilder = new VpnTargetsBuilder().setVpnTarget(opVpnTargetList);
             builder.setVpnTargets(vpnTargetsBuilder.build());
 
-            List<String> rds = config.getRouteDistinguisher();
+            List<String> rds = value.getRouteDistinguisher();
             builder.setRd(rds);
         } else {
             builder.setBgpvpnType(VpnInstanceOpDataEntry.BgpvpnType.VPN);
@@ -343,8 +341,7 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase<VpnInst
             if rd is null, then its either a router vpn instance (or) a vlan external network vpn instance.
             if rd is non-null, then it is a bgpvpn instance
              */
-            VpnAfConfig config = vpnInstance.getIpv4Family();
-            List<String> rd = config.getRouteDistinguisher();
+            List<String> rd = vpnInstance.getRouteDistinguisher();
             if (rd == null || addBgpVrf()) {
                 notifyTask();
                 vpnInterfaceManager.vpnInstanceIsReady(vpnName);
@@ -387,9 +384,8 @@ public class VpnInstanceListener extends AsyncDataTreeChangeListenerBase<VpnInst
         // TODO Clean up the exception handling
         @SuppressWarnings("checkstyle:IllegalCatch")
         private boolean addBgpVrf() {
-            VpnAfConfig config = vpnInstance.getIpv4Family();
             String primaryRd = vpnUtil.getPrimaryRd(vpnName);
-            List<VpnTarget> vpnTargetList = config.getVpnTargets().getVpnTarget();
+            List<VpnTarget> vpnTargetList = vpnInstance.getVpnTargets().getVpnTarget();
 
             if (vpnTargetList == null) {
                 log.error("{} addBgpVrf: vpn target list is empty for vpn {} RD {}", LOGGING_PREFIX_ADD,
index a668c2f6dff8b608ebaaaa970fd72cc3c8a92d32..4dfde8026d09fcad47104a9c303562e81846c0df 100644 (file)
@@ -84,8 +84,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.sub
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.Routes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.Adjacency;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTarget;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTarget;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.vpn.portip.port.data.VpnPortipToPort;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -682,7 +682,7 @@ public class VpnManagerImpl implements IVpnManager {
 
     @Override
     public Set<VpnTarget> getRtListForVpn(String vpnName) {
-        return vpnUtil.getRtListForVpn(vpnName);
+        return vpnUtil.getRtListForVpn(dataBroker, vpnName);
     }
 
     @Override
index fc7f7fb0852900ea87cb90a1cc10dc95f9203752..bb8f13ef9ab6f5bee7115eb7e3e0c9436b89eabc 100644 (file)
@@ -125,14 +125,25 @@ public class VpnOpStatusListener extends AsyncDataTreeChangeListenerBase<VpnInst
                                 rds.parallelStream().forEach(rd -> bgpManager.deleteVrf(
                                         rd, false, AddressFamily.L2VPN));
                             }
-                            if (update.isIpv4Configured()) {
+                            if (update.getIpAddressFamilyConfigured()
+                                    == VpnInstanceOpDataEntry.IpAddressFamilyConfigured.Ipv4) {
                                 rds.parallelStream().forEach(rd -> bgpManager.deleteVrf(
                                         rd, false, AddressFamily.IPV4));
                             }
-                            if (update.isIpv6Configured()) {
+                            if (update.getIpAddressFamilyConfigured()
+                                    == VpnInstanceOpDataEntry.IpAddressFamilyConfigured.Ipv6) {
                                 rds.parallelStream().forEach(rd -> bgpManager.deleteVrf(
                                         rd, false, AddressFamily.IPV6));
                             }
+                            if (update.getIpAddressFamilyConfigured()
+                                    == VpnInstanceOpDataEntry.IpAddressFamilyConfigured.Ipv4AndIpv6) {
+                                rds.parallelStream()
+                                        .forEach(rd -> bgpManager.deleteVrf(
+                                                rd, false, AddressFamily.IPV4));
+                                rds.parallelStream()
+                                        .forEach(rd -> bgpManager.deleteVrf(
+                                                rd, false, AddressFamily.IPV6));
+                            }
                         }
                         InstanceIdentifier<Vpn> vpnToExtraroute =
                                 VpnExtraRouteHelper.getVpnToExtrarouteVpnIdentifier(vpnName);
@@ -259,30 +270,41 @@ public class VpnOpStatusListener extends AsyncDataTreeChangeListenerBase<VpnInst
                     try {
                         List<String> importRTList = rd.equals(primaryRd) ? irtList : emptyList();
                         LOG.info("VpnOpStatusListener.update: updating BGPVPN for vpn {} with RD {}"
-                                + " Type is {}, IPv4 is {}, IPv6 is {}, iRT {}", vpnName, primaryRd, update.getType(),
-                                update.isIpv4Configured(), update.isIpv6Configured(), importRTList);
-                        if (update.getType() == VpnInstanceOpDataEntry.Type.L2) {
-                            bgpManager.addVrf(rd, importRTList, ertList, AddressFamily.L2VPN);
-                        }
-                        if (!original.isIpv4Configured() && update.isIpv4Configured()) {
-                            bgpManager.addVrf(rd, importRTList, ertList, AddressFamily.IPV4);
-                        } else if (original.isIpv4Configured() && !update.isIpv4Configured()) {
-                            bgpManager.deleteVrf(rd, false, AddressFamily.IPV4);
-                        }
-                        if (!original.isIpv6Configured() && update.isIpv6Configured()) {
-                            bgpManager.addVrf(rd, importRTList, ertList, AddressFamily.IPV6);
-                        } else if (original.isIpv6Configured() && !update.isIpv6Configured()) {
-                            bgpManager.deleteVrf(rd, false, AddressFamily.IPV6);
+                                + " Type is {}, IPtype is {}, iRT {}", vpnName, primaryRd, update.getType(),
+                                update.getIpAddressFamilyConfigured(), importRTList);
+                        int ipValue = VpnUtil.getIpFamilyValueToRemove(original,update);
+                        switch (ipValue) {
+                            case 4:
+                                bgpManager.deleteVrf(rd, false, AddressFamily.IPV4);
+                                break;
+                            case 6:
+                                bgpManager.deleteVrf(rd, false, AddressFamily.IPV6);
+                                break;
+                            case 10:
+                                bgpManager.deleteVrf(rd, false, AddressFamily.IPV4);
+                                bgpManager.deleteVrf(rd, false, AddressFamily.IPV6);
+                                break;
+                            default:
+                                break;
                         }
                         /* Update vrf entry with newly added RD list. VPN does not support for
                          * deleting existing RDs
                          */
                         if (original.getRd().size() != update.getRd().size()) {
-                            if (update.isIpv4Configured()) {
-                                bgpManager.addVrf(rd, importRTList, ertList, AddressFamily.IPV4);
-                            }
-                            if (update.isIpv6Configured()) {
-                                bgpManager.addVrf(rd, importRTList, ertList, AddressFamily.IPV6);
+                            ipValue = VpnUtil.getIpFamilyValueToAdd(original,update);
+                            switch (ipValue) {
+                                case 4:
+                                    bgpManager.addVrf(rd, importRTList, ertList, AddressFamily.IPV4);
+                                    break;
+                                case 6:
+                                    bgpManager.addVrf(rd, importRTList, ertList, AddressFamily.IPV6);
+                                    break;
+                                case 10:
+                                    bgpManager.addVrf(rd, importRTList, ertList, AddressFamily.IPV4);
+                                    bgpManager.addVrf(rd, importRTList, ertList, AddressFamily.IPV6);
+                                    break;
+                                default:
+                                    break;
                             }
                         }
                     } catch (RuntimeException e) {
index 9249f2f09917772fcb63b6bad8c11a025aa77111..484d8a647f39f6214764bb92063e6ebc20d70083 100644 (file)
@@ -209,7 +209,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitchKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.Adjacencies;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.AdjacenciesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnAfConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.adjacency.list.Adjacency;
@@ -465,10 +464,8 @@ public final class VpnUtil {
 
     @NonNull
     static List<String> getListOfRdsFromVpnInstance(VpnInstance vpnInstance) {
-        VpnAfConfig vpnConfig = vpnInstance.getIpv4Family();
-        LOG.trace("vpnConfig {}", vpnConfig);
-        return vpnConfig.getRouteDistinguisher() != null && vpnConfig.getRouteDistinguisher() != null
-            ? vpnConfig.getRouteDistinguisher() : emptyList();
+        return vpnInstance.getRouteDistinguisher() != null ? new ArrayList<>(
+                vpnInstance.getRouteDistinguisher()) : new ArrayList<>();
     }
 
     @Nullable
@@ -2266,26 +2263,73 @@ public final class VpnUtil {
         }
     }
 
-    Set<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config
-            .vpntargets.VpnTarget> getRtListForVpn(String vpnName) {
-        Set<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets
-                .VpnTarget> rtList = new HashSet<>();
-        InstanceIdentifier<VpnInstance> vpnInstanceId = InstanceIdentifier.builder(VpnInstances.class)
-                .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
-        Optional<VpnInstance> vpnInstanceOptional = read(LogicalDatastoreType.CONFIGURATION, vpnInstanceId);
-        if (vpnInstanceOptional.isPresent()) {
-            org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.VpnTargets
-                    vpnTargets = vpnInstanceOptional.get().getIpv4Family().getVpnTargets();
-            if (vpnTargets != null && vpnTargets.getVpnTarget() != null) {
-                rtList.addAll(vpnTargets.getVpnTarget());
+    static Set<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn
+            .instance.vpntargets.VpnTarget> getRtListForVpn(DataBroker dataBroker, String vpnName) {
+        Set<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn
+                .instance.vpntargets.VpnTarget> rtList = new HashSet<>();
+        try {
+            InstanceIdentifier<VpnInstance> vpnInstanceId = InstanceIdentifier.builder(VpnInstances.class)
+                    .child(VpnInstance.class, new VpnInstanceKey(vpnName)).build();
+            Optional<VpnInstance> vpnInstanceOptional = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                    LogicalDatastoreType.CONFIGURATION, vpnInstanceId);
+            if (vpnInstanceOptional.isPresent()) {
+                org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances
+                        .vpn.instance.VpnTargets vpnTargets = vpnInstanceOptional.get().getVpnTargets();
+                if (vpnTargets != null && vpnTargets.getVpnTarget() != null) {
+                    rtList.addAll(vpnTargets.getVpnTarget());
+                }
+            } else {
+                LOG.error("getRtListForVpn: Vpn Instance {} not present in config DS", vpnName);
             }
-        }
-        else {
-            LOG.error("getRtListForVpn: Vpn Instance {} not present in config DS", vpnName);
+        } catch (ReadFailedException e) {
+            LOG.error("getRtListForVpn: Read failed for Vpn Instance {}", vpnName);
         }
         return rtList;
     }
 
+    /*
+    if (update == 0) {
+    removedFamily = original
+    4 removed = 4
+    6 removed = 6
+    10 removed
+    } else if (update < original) {
+    removedFamily = original - update
+    10 was there 4 removed = 6
+    10 was there 6 removed  = 4
+    } else {
+   return;
+    }
+    */
+    public static int getIpFamilyValueToRemove(VpnInstanceOpDataEntry original, VpnInstanceOpDataEntry update) {
+        int originalValue = original.getIpAddressFamilyConfigured().getIntValue();
+        int updatedValue = update.getIpAddressFamilyConfigured().getIntValue();
+
+        if (originalValue == updatedValue) {
+            return 0;
+        }
+        int removedFamily;
+        if (updatedValue == 0) {
+            removedFamily = originalValue;
+        } else if (updatedValue < originalValue) {
+            removedFamily = originalValue - updatedValue;
+        } else {
+            return 0;
+        }
+        return removedFamily;
+    }
+
+    public static int getIpFamilyValueToAdd(VpnInstanceOpDataEntry original, VpnInstanceOpDataEntry update) {
+        int originalValue = original.getIpAddressFamilyConfigured().getIntValue();
+        int updatedValue = update.getIpAddressFamilyConfigured().getIntValue();
+
+        if (originalValue != updatedValue) {
+            return updatedValue;
+        } else {
+            return originalValue;
+        }
+    }
+
     static InstanceIdentifier<AssociatedVpn> getAssociatedSubnetAndVpnIdentifier(String rt, RouteTarget.RtType rtType,
                                                                                  String cidr, String vpnName) {
         return InstanceIdentifier.builder(SubnetsAssociatedToRouteTargets.class).child(RouteTarget.class,
@@ -2309,10 +2353,10 @@ public final class VpnUtil {
     }
 
     Set<RouteTarget> getRouteTargetSet(Set<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn
-            .rev200204.vpn.af.config.vpntargets.VpnTarget> vpnTargets) {
+            .rev200204.vpn.instances.vpn.instance.vpntargets.VpnTarget> vpnTargets) {
         Set<RouteTarget> routeTargetSet = new HashSet<>();
-        for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets
-                .VpnTarget rt : vpnTargets) {
+        for (org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn
+                .instance.vpntargets.VpnTarget rt : vpnTargets) {
             String rtValue = rt.getVrfRTValue();
             switch (rt.getVrfRTType()) {
                 case ImportExtcommunity: {
index a9a0009add090117eedba9bbbe42c616fefb7bd9..22f3b90c6a919d639dea1cd1ea21d6dd41539364 100644 (file)
@@ -15,15 +15,13 @@ import java.util.stream.Collectors;
 import org.opendaylight.netvirt.vpnmanager.VpnOperDsUtils;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.VpnTargets;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.VpnTargetsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTarget;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTargetBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTargetKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.Ipv4Family;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.VpnTargets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.VpnTargetsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTarget;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTargetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTargetKey;
 
 /**
  * Gathers a collections of 'fake' L3VPN objects that can be used in JUnits.
@@ -68,12 +66,11 @@ public final class L3VpnTestCatalog {
     static L3VpnComposite build(String vpnName, String vpnRd, long vpnTag, List<String> irts, List<String> erts) {
         Objects.nonNull(irts);
         Objects.nonNull(erts);
-        Ipv4Family vpnIpv4Cfg = new Ipv4FamilyBuilder().setVpnTargets(makeVpnTargets(irts, erts)).build();
         VpnInstance vpnInst =
-            new VpnInstanceBuilder().setVpnInstanceName(vpnName).setIpv4Family(vpnIpv4Cfg).build();
+                new VpnInstanceBuilder().setVpnInstanceName(vpnName).setVpnTargets(makeVpnTargets(irts, erts)).build();
         VpnInstanceOpDataEntry vpnOpData =
-            new VpnInstanceOpDataEntryBuilder().setVpnId(vpnTag).setVpnInstanceName(vpnName).setVrfId(vpnRd)
-                                               .setVpnTargets(VpnOperDsUtils.makeVpnTargets(irts, erts)).build();
+                new VpnInstanceOpDataEntryBuilder().setVpnId(vpnTag).setVpnInstanceName(vpnName).setVrfId(vpnRd)
+                        .setVpnTargets(VpnOperDsUtils.makeVpnTargets(irts, erts)).build();
         return new L3VpnComposite(vpnInst, vpnOpData);
     }
 
index 1ef2f5b7d7324a3b1cef208d83d4afe355092bf9..0eaeef9c36220e9c5db12504e055ae48d0f9fcda 100644 (file)
@@ -18,18 +18,14 @@ import org.mockito.junit.MockitoJUnitRunner;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.ApplyLabelBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.VpnTargets;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.VpnTargetsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.apply.label.apply.label.mode.PerRouteBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTarget;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTargetBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.af.config.vpntargets.VpnTargetKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstanceKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.Ipv4Family;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.VpnTargets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.VpnTargetsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTarget;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTargetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTargetKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
 
@@ -59,12 +55,9 @@ public class VpnServiceTest {
 
         VpnTargets vpnTargets = new VpnTargetsBuilder().setVpnTarget(vpnTargetList).build();
 
-        Ipv4Family ipv4Family = new Ipv4FamilyBuilder().setRouteDistinguisher(Arrays.asList("100:1","100:2:"))
-                .setVpnTargets(vpnTargets).setApplyLabel(new ApplyLabelBuilder().setApplyLabelMode(
-                            new PerRouteBuilder().setApplyLabelPerRoute(true).build()).build()).build();
-
         VpnInstanceBuilder builder =
-            new VpnInstanceBuilder().withKey(new VpnInstanceKey("Vpn1")).setIpv4Family(ipv4Family);
+                new VpnInstanceBuilder().withKey(new VpnInstanceKey("Vpn1"))
+                        .setRouteDistinguisher(Arrays.asList("100:1","100:2:")).setVpnTargets(vpnTargets);
         VpnInstance instance = builder.build();
         //TODO: Need to enhance the test case to handle ds read/write ops
         //vpnManager.onDataChanged(event);
index 4bd3b2f927336de7257d2add7443cf049fcb644a..1a9cfeed2190f201fb42b6439ee07ed8adaf1645 100644 (file)
@@ -84,8 +84,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.networks.NetworksKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.Ipv4Family;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.Ipv4FamilyBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapBuilder;
@@ -125,7 +123,6 @@ public class VpnSubnetRouteHandlerTest {
     DPNTEPsInfo dpntePsInfo = null;
     TunnelEndPoints tunlEndPts = null;
     IpAddress ipAddress = null;
-    Ipv4Family ipv4Family = null;
     String idKey = null;
     AllocateIdOutput allocateIdOutput = null;
     AllocateIdInput allocateIdInput = null;
@@ -305,11 +302,10 @@ public class VpnSubnetRouteHandlerTest {
         tunlEndPts =
             new TunnelEndPointsBuilder().setInterfaceName(interfaceName).setIpAddress(ipAddress).build();
         tunnelEndPoints.add(tunlEndPts);
-        ipv4Family = new Ipv4FamilyBuilder().setRouteDistinguisher(routeDistinguishers).build();
         vpnInstnce = new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances
             .VpnInstanceBuilder().withKey(new org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn
                 .rev200204.vpn.instances.VpnInstanceKey(interfaceName)).setVpnInstanceName(interfaceName)
-            .setIpv4Family(ipv4Family).build();
+            .setRouteDistinguisher(routeDistinguishers).build();
         networks = new NetworksBuilder().setId(portId).withKey(new NetworksKey(portId)).build();
         doReturn(mockReadTx).when(dataBroker).newReadOnlyTransaction();
         doReturn(mockWriteTx).when(dataBroker).newWriteOnlyTransaction();
index d739805e7dcc90c02057b7df18fd83c8fc2c7c3f..f8dc27ca0bec839fea3f0ebc6384aeac4071a701 100644 (file)
@@ -26,7 +26,6 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.netvirt.vpnmanager.api.VpnHelper;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInterfaceOpData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn._interface.op.data.VpnInterfaceOpDataEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnAfConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
@@ -116,12 +115,9 @@ public class ShowVpn extends OsgiCommandSupport {
                     operCount = vpnNameToOperInterfaceMap.get(vpnInstance.getVpnInstanceName());
                     totalOperCount = totalOperCount + operCount;
                 }
-                VpnAfConfig addrFamily = vpnInstance.getIpv4Family() != null ? vpnInstance.getIpv4Family() :
-                    vpnInstance.getIpv6Family();
-
                 session.getConsole().println(
                         String.format("%-32s  %-10s  %-10s  %-10s", vpnInstance.getVpnInstanceName(),
-                                addrFamily.getRouteDistinguisher(), configCount, operCount));
+                                vpnInstance.getRouteDistinguisher(), configCount, operCount));
             }
             session.getConsole().println("-----------------------------------------------------------------------");
             session.getConsole().println(