Add support of IPv6 VPN ext (RFC4659) for BGP-MPLS 84/36984/19
authorKevin Wang <kevixw@gmail.com>
Fri, 1 Apr 2016 00:17:13 +0000 (00:17 +0000)
committerMilos Fabian <milfabia@cisco.com>
Fri, 29 Apr 2016 13:24:09 +0000 (13:24 +0000)
Change-Id: Iaebcb20ed461667626f13c44e2011610212f8893
Signed-off-by: Kevin Wang <kevixw@gmail.com>
30 files changed:
bgp/controller-config/src/main/resources/initial/31-bgp.xml
bgp/controller-config/src/main/resources/initial/41-bgp-example.xml
bgp/l3vpn/src/main/java/org/opendaylight/controller/config/yang/bgp/vpn/ipv4/VpnIpv4Module.java
bgp/l3vpn/src/main/java/org/opendaylight/controller/config/yang/bgp/vpn/ipv6/VpnIpv6Module.java [new file with mode: 0644]
bgp/l3vpn/src/main/java/org/opendaylight/controller/config/yang/bgp/vpn/ipv6/VpnIpv6ModuleFactory.java [new file with mode: 0644]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/AbstractVpnNextHopParserSerializer.java [moved from bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/VpnIpv4NextHopParserSerializer.java with 55% similarity]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/AbstractVpnNlriParser.java [moved from bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/VpnIpv4NlriParser.java with 54% similarity]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/AbstractVpnRIBSupport.java [new file with mode: 0644]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/VpnIpv4RIBSupport.java [deleted file]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/BgpIpv4Activator.java [moved from bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/BGPActivator.java with 88% similarity]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/RibIpv4Activator.java [moved from bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/RIBActivator.java with 89% similarity]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4NextHopParserSerializer.java [new file with mode: 0644]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4NlriParser.java [new file with mode: 0644]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4RIBSupport.java [new file with mode: 0644]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/BgpIpv6Activator.java [new file with mode: 0644]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/RibIpv6Activator.java [new file with mode: 0644]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6NextHopParserSerializer.java [new file with mode: 0644]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6NlriParser.java [new file with mode: 0644]
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6RIBSupport.java [new file with mode: 0644]
bgp/l3vpn/src/main/yang/bgp-vpn-ipv4.yang
bgp/l3vpn/src/main/yang/bgp-vpn-ipv6.yang [new file with mode: 0644]
bgp/l3vpn/src/main/yang/bgp-vpn.yang [new file with mode: 0644]
bgp/l3vpn/src/main/yang/odl-bgp-vpn-ipv6-cfg.yang [new file with mode: 0644]
bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/BgpIpv4ActivatorTest.java [moved from bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/BGPActivatorTest.java with 87% similarity]
bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4NextHopTest.java [moved from bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/VpnIpv4NextHopTest.java with 97% similarity]
bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4NlriParserTest.java [moved from bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/VpnIpv4NlriParserTest.java with 73% similarity]
bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/BgpIpv6ActivatorTest.java [new file with mode: 0644]
bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6NextHopTest.java [new file with mode: 0644]
bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6NlriParserTest.java [new file with mode: 0644]
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/AbstractRIBSupport.java

index 45d1df70630d56d97fc35e22df173899ed440bdf..20215a9edac7c5e250361197ba2063c95f847b18 100644 (file)
@@ -15,6 +15,7 @@
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:flowspec?module=odl-bgp-flowspec-cfg&amp;revision=2015-04-23</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:labeled:unicast?module=odl-bgp-labeled-unicast-cfg&amp;revision=2015-05-25</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:vpn:ipv4?module=odl-bgp-vpn-ipv4-cfg&amp;revision=2016-02-19</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:vpn:ipv6?module=odl-bgp-vpn-ipv6-cfg&amp;revision=2016-03-31</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:evpn?module=odl-bgp-evpn-cfg&amp;revision=2016-03-21</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:parser:spi?module=odl-bgp-parser-spi-cfg&amp;revision=2013-11-15</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:spi?module=odl-bgp-rib-spi-cfg&amp;revision=2013-11-15</capability>
                         <type xmlns:bgpspi="urn:opendaylight:params:xml:ns:yang:controller:bgp:parser:spi">bgpspi:extension</type>
                         <name>bgp-vpn-ipv4</name>
                     </extension>
+                    <extension>
+                        <type xmlns:bgpspi="urn:opendaylight:params:xml:ns:yang:controller:bgp:parser:spi">bgpspi:extension</type>
+                        <name>bgp-vpn-ipv6</name>
+                    </extension>
                     <extension>
                         <type xmlns:bgpspi="urn:opendaylight:params:xml:ns:yang:controller:bgp:parser:spi">bgpspi:extension</type>
                         <name>bgp-evpn</name>
                         <type xmlns:ribspi="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:spi">ribspi:extension</type>
                         <name>bgp-vpn-ipv4</name>
                     </extension>
+                    <extension>
+                        <type xmlns:ribspi="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:spi">ribspi:extension</type>
+                        <name>bgp-vpn-ipv6</name>
+                    </extension>
                     <extension>
                         <type xmlns:ribspi="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:spi">ribspi:extension</type>
                         <name>bgp-evpn</name>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:vpn:ipv4">prefix:bgp-vpn-ipv4</type>
                     <name>bgp-vpn-ipv4</name>
                 </module>
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:vpn:ipv6">prefix:bgp-vpn-ipv6</type>
+                    <name>bgp-vpn-ipv6</name>
+                </module>
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:evpn">prefix:bgp-evpn</type>
                     <name>bgp-evpn</name>
                     <afi xmlns:bgp="urn:opendaylight:params:xml:ns:yang:bgp-types">bgp:ipv4-address-family</afi>
                     <safi xmlns:bgp-types="urn:opendaylight:params:xml:ns:yang:bgp-types">bgp-types:mpls-labeled-vpn-subsequent-address-family</safi>
                 </module>
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type-impl</type>
+                    <name>ipv6-l3vpn</name>
+                    <afi xmlns:bgp="urn:opendaylight:params:xml:ns:yang:bgp-types">bgp:ipv6-address-family</afi>
+                    <safi xmlns:bgp-types="urn:opendaylight:params:xml:ns:yang:bgp-types">bgp-types:mpls-labeled-vpn-subsequent-address-family</safi>
+                </module>
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type-impl</type>
                     <name>evpn</name>
                         <name>bgp-vpn-ipv4</name>
                         <provider>/modules/module[type='bgp-vpn-ipv4'][name='bgp-vpn-ipv4']</provider>
                     </instance>
+                    <instance>
+                        <name>bgp-vpn-ipv6</name>
+                        <provider>/modules/module[type='bgp-vpn-ipv6'][name='bgp-vpn-ipv6']</provider>
+                    </instance>
                     <instance>
                         <name>bgp-evpn</name>
                         <provider>/modules/module[type='bgp-evpn'][name='bgp-evpn']</provider>
                         <name>ipv4-l3vpn</name>
                         <provider>/modules/module[type='bgp-table-type-impl'][name='ipv4-l3vpn']</provider>
                     </instance>
+                    <instance>
+                        <name>ipv6-l3vpn</name>
+                        <provider>/modules/module[type='bgp-table-type-impl'][name='ipv6-l3vpn']</provider>
+                    </instance>
                     <instance>
                         <name>evpn</name>
                         <provider>/modules/module[type='bgp-table-type-impl'][name='evpn']</provider>
                         <name>bgp-vpn-ipv4</name>
                         <provider>/modules/module[type='bgp-vpn-ipv4'][name='bgp-vpn-ipv4']</provider>
                     </instance>
+                    <instance>
+                        <name>bgp-vpn-ipv6</name>
+                        <provider>/modules/module[type='bgp-vpn-ipv6'][name='bgp-vpn-ipv6']</provider>
+                    </instance>
                     <instance>
                         <name>bgp-evpn</name>
                         <provider>/modules/module[type='bgp-evpn'][name='bgp-evpn']</provider>
index 10edd367c8432b1414b7a4114ae851d8f3248982..56a226e04f31c33480b6dee0e1767b176bdcde3e 100755 (executable)
@@ -66,7 +66,6 @@
                     </path-selection-mode>
                 </module>-->
 
-
                 <!--
                      A single BGP peer. Note this section is deactivated because a misconfigured peer
                      tends to log rather nasty error messages.
                         <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type</type>
                         <name>ipv4-l3vpn</name>
                     </advertized-table>
+                    <advertized-table>
+                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type</type>
+                        <name>ipv6-l3vpn</name>
+                    </advertized-table>
                     <advertized-table>
                         <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type</type>
                         <name>evpn</name>
                         <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:add-path</type>
                         <name>ipv4-unicast-both</name>
                     </add-path>
+                    <add-path>
+                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:add-path</type>
+                        <name>ipv6-unicast-both</name>
+                    </add-path>
                 </module>
                 -->
 
                         <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type</type>
                         <name>ipv4-l3vpn</name>
                     </local-table>
+                    <local-table>
+                        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type</type>
+                        <name>ipv6-l3vpn</name>
+                    </local-table>
                     <local-table>
                         <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type</type>
                         <name>evpn</name>
index 088b0d49c9369a38d72934046523579b3ebedc22..8904dd4f12137287d6c2c31d44d5a11bda35ee8d 100644 (file)
@@ -7,8 +7,8 @@
  */
 package org.opendaylight.controller.config.yang.bgp.vpn.ipv4;
 
-import org.opendaylight.protocol.bgp.l3vpn.BGPActivator;
-import org.opendaylight.protocol.bgp.l3vpn.RIBActivator;
+import org.opendaylight.protocol.bgp.l3vpn.ipv4.BgpIpv4Activator;
+import org.opendaylight.protocol.bgp.l3vpn.ipv4.RibIpv4Activator;
 import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderActivator;
 import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderActivator;
@@ -31,8 +31,8 @@ public class VpnIpv4Module extends AbstractVpnIpv4Module {
     @Override
     public java.lang.AutoCloseable createInstance() {
         final class VpnIpv4Extension implements AutoCloseable, BGPExtensionProviderActivator, RIBExtensionProviderActivator {
-            private final BGPExtensionProviderActivator bgpact = new BGPActivator();
-            private final RIBExtensionProviderActivator ribact = new RIBActivator();
+            private final BGPExtensionProviderActivator bgpact = new BgpIpv4Activator();
+            private final RIBExtensionProviderActivator ribact = new RibIpv4Activator();
             @Override
             public void startRIBExtensionProvider(
                 final RIBExtensionProviderContext context) {
diff --git a/bgp/l3vpn/src/main/java/org/opendaylight/controller/config/yang/bgp/vpn/ipv6/VpnIpv6Module.java b/bgp/l3vpn/src/main/java/org/opendaylight/controller/config/yang/bgp/vpn/ipv6/VpnIpv6Module.java
new file mode 100644 (file)
index 0000000..9d222dc
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yang.bgp.vpn.ipv6;
+
+import org.opendaylight.protocol.bgp.l3vpn.ipv6.BgpIpv6Activator;
+import org.opendaylight.protocol.bgp.l3vpn.ipv6.RibIpv6Activator;
+import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderActivator;
+import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
+import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderActivator;
+import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
+
+public class VpnIpv6Module extends org.opendaylight.controller.config.yang.bgp.vpn.ipv6.AbstractVpnIpv6Module {
+    public VpnIpv6Module(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+        super(identifier, dependencyResolver);
+    }
+
+    public VpnIpv6Module(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.bgp.vpn.ipv6.VpnIpv6Module oldModule, java.lang.AutoCloseable oldInstance) {
+        super(identifier, dependencyResolver, oldModule, oldInstance);
+    }
+
+    @Override
+    public void customValidation() {
+        // add custom validation form module attributes here.
+    }
+
+    @Override
+    public java.lang.AutoCloseable createInstance() {
+        final class VpnIpv6Extension implements AutoCloseable, BGPExtensionProviderActivator, RIBExtensionProviderActivator {
+            private final BGPExtensionProviderActivator bgpact = new BgpIpv6Activator();
+            private final RIBExtensionProviderActivator ribact = new RibIpv6Activator();
+
+            @Override
+            public void startRIBExtensionProvider(
+                final RIBExtensionProviderContext context) {
+                this.ribact.startRIBExtensionProvider(context);
+            }
+
+            @Override
+            public void stopRIBExtensionProvider() {
+                this.ribact.stopRIBExtensionProvider();
+            }
+
+            @Override
+            public void start(final BGPExtensionProviderContext context) {
+                this.bgpact.start(context);
+            }
+
+            @Override
+            public void stop() {
+                this.bgpact.stop();
+            }
+
+            @Override
+            public void close() throws Exception {
+                if (this.bgpact != null) {
+                    this.bgpact.stop();
+                }
+                if (this.ribact != null) {
+                    this.ribact.stopRIBExtensionProvider();
+                }
+            }
+        }
+        return new VpnIpv6Extension();
+    }
+
+}
diff --git a/bgp/l3vpn/src/main/java/org/opendaylight/controller/config/yang/bgp/vpn/ipv6/VpnIpv6ModuleFactory.java b/bgp/l3vpn/src/main/java/org/opendaylight/controller/config/yang/bgp/vpn/ipv6/VpnIpv6ModuleFactory.java
new file mode 100644 (file)
index 0000000..58d18aa
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yang.bgp.vpn.ipv6;
+
+public class VpnIpv6ModuleFactory extends org.opendaylight.controller.config.yang.bgp.vpn.ipv6.AbstractVpnIpv6ModuleFactory {
+
+}
similarity index 55%
rename from bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/VpnIpv4NextHopParserSerializer.java
rename to bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/AbstractVpnNextHopParserSerializer.java
index a209f9a78597e2f33d7100ba4479c9dc186c0e60..78ca9ee65b7af409589c90d04010011dcf7ec8fc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -13,24 +13,31 @@ import org.opendaylight.bgp.concepts.NextHopUtil;
 import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.NextHopParserSerializer;
-import org.opendaylight.protocol.util.Ipv4Util;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
 
-public final class VpnIpv4NextHopParserSerializer implements NextHopParserSerializer {
+/**
+ * @author Kevin Wang
+ */
+public abstract class AbstractVpnNextHopParserSerializer implements NextHopParserSerializer {
+    private final int IP_ADDR_LENGTH;
+    private final Class<?> IP_NEXT_HOP_CASE_CLAZZ;
+
+    protected AbstractVpnNextHopParserSerializer(final int ipAddrLength, final Class<?> ipNextHopCaseClazz) {
+        IP_ADDR_LENGTH = ipAddrLength;
+        IP_NEXT_HOP_CASE_CLAZZ = ipNextHopCaseClazz;
+    }
 
     @Override
     public CNextHop parseNextHop(final ByteBuf buffer) throws BGPParsingException {
-        Preconditions.checkArgument(buffer.readableBytes() == (Ipv4Util.IP4_LENGTH + RouteDistinguisherUtil.RD_LENGTH), "Length of byte array for NEXT_HOP should be %s, but is %s", Ipv4Util.IP4_LENGTH + RouteDistinguisherUtil.RD_LENGTH, buffer.readableBytes());
+        Preconditions.checkArgument(buffer.readableBytes() == (IP_ADDR_LENGTH + RouteDistinguisherUtil.RD_LENGTH), "Length of byte array for NEXT_HOP should be %s, but is %s", IP_ADDR_LENGTH + RouteDistinguisherUtil.RD_LENGTH, buffer.readableBytes());
         buffer.readBytes(RouteDistinguisherUtil.RD_LENGTH);
-        return NextHopUtil.parseNextHop(buffer.readBytes(Ipv4Util.IP4_LENGTH));
+        return NextHopUtil.parseNextHop(buffer.readBytes(IP_ADDR_LENGTH));
     }
 
     @Override
     public void serializeNextHop(final CNextHop cNextHop, final ByteBuf byteAggregator) {
-        Preconditions.checkArgument(cNextHop instanceof Ipv4NextHopCase, "cNextHop is not a VPN Ipv4 NextHop object.");
+        Preconditions.checkArgument(IP_NEXT_HOP_CASE_CLAZZ.isInstance(cNextHop), "cNextHop is not a VPN %s NextHop object.", IP_NEXT_HOP_CASE_CLAZZ.getSimpleName());
         byteAggregator.writeZero(RouteDistinguisherUtil.RD_LENGTH);
         NextHopUtil.serializeNextHop(cNextHop, byteAggregator);
     }
-
 }
similarity index 54%
rename from bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/VpnIpv4NlriParser.java
rename to bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/AbstractVpnNlriParser.java
index 82749a20953f4122933b2d5cf0897c95dbc8fcb7..ff10e797219e851175867075c993f5339b2638ac 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -22,104 +22,106 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labe
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv4CaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.vpn.ipv4._case.DestinationVpnIpv4Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv4Case;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.vpn.ipv4.destination.VpnIpv4Destination;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.vpn.ipv4.destination.VpnIpv4DestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestinationBuilder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public class VpnIpv4NlriParser implements NlriParser, NlriSerializer {
+/**
+ * @author Kevin Wang
+ */
+public abstract class AbstractVpnNlriParser implements NlriParser, NlriSerializer {
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractVpnNlriParser.class);
 
-    @Override
-    public void serializeAttribute(final DataObject attribute, final ByteBuf byteAggregator) {
-        Preconditions.checkArgument(attribute instanceof Attributes, "Attribute parameter is not a Attributes object");
-        final Attributes pathAttributes = (Attributes) attribute;
-        final Attributes1 pathAttributes1 = pathAttributes.getAugmentation(Attributes1.class);
-        final Attributes2 pathAttributes2 = pathAttributes.getAugmentation(Attributes2.class);
-        if (pathAttributes1 != null) {
-            final AdvertizedRoutes routes = (pathAttributes1.getMpReachNlri()).getAdvertizedRoutes();
-            if ((routes != null) && (routes.getDestinationType() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv4Case)) {
-                final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv4Case labeledUnicastCase = (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv4Case) routes.getDestinationType();
-                serializeNlri(labeledUnicastCase.getDestinationVpnIpv4().getVpnIpv4Destination(), byteAggregator);
-            }
-        } else if (pathAttributes2 != null) {
-            final MpUnreachNlri mpUnreachNlri = pathAttributes2.getMpUnreachNlri();
-            if ((mpUnreachNlri.getWithdrawnRoutes() != null) && (mpUnreachNlri.getWithdrawnRoutes().getDestinationType() instanceof DestinationVpnIpv4Case)) {
-                final DestinationVpnIpv4Case labeledUnicastCase = (DestinationVpnIpv4Case) mpUnreachNlri.getWithdrawnRoutes().getDestinationType();
-                serializeNlri(labeledUnicastCase.getDestinationVpnIpv4().getVpnIpv4Destination(), byteAggregator);
-            }
-        }
-    }
+    protected abstract List<VpnDestination> getWithdrawnVpnDestination(DestinationType dstType);
+
+    protected abstract List<VpnDestination> getAdvertizedVpnDestination(DestinationType dstType);
+
+    protected abstract WithdrawnRoutes getWithdrawnRoutesByDestination(List<VpnDestination> dst);
 
-    protected static void serializeNlri(final List<VpnIpv4Destination> dests, final ByteBuf buffer) {
+    protected abstract AdvertizedRoutes getAdvertizedRoutesByDestination(List<VpnDestination> dst);
+
+    public static void serializeNlri(final List<VpnDestination> dests, final ByteBuf buffer) {
         final ByteBuf nlriByteBuf = Unpooled.buffer();
-        for (final VpnIpv4Destination dest: dests) {
+        for (final VpnDestination dest : dests) {
             final List<LabelStack> labelStack = dest.getLabelStack();
             final IpPrefix prefix = dest.getPrefix();
+            LOG.debug("Serializing Nlri: VpnDestination={}, IpPrefix={}", dest, prefix);
             // Serialize the length field
             // Length field contains one Byte which represents the length of label stack and prefix in bits
             nlriByteBuf.writeByte(((LUNlriParser.LABEL_LENGTH * labelStack.size()) + LUNlriParser.getPrefixLength(prefix) + RouteDistinguisherUtil.RD_LENGTH) * Byte.SIZE);
-
             LUNlriParser.serializeLabelStackEntries(labelStack, nlriByteBuf);
             RouteDistinguisherUtil.serializeRouteDistinquisher(dest.getRouteDistinguisher(), nlriByteBuf);
-            Preconditions.checkNotNull(prefix.getIpv4Prefix(), "Ipv4 prefix is missing.");
+            Preconditions.checkArgument(prefix.getIpv6Prefix() != null || prefix.getIpv4Prefix() != null, "Ipv6 or Ipv4 prefix is missing.");
             LUNlriParser.serializePrefixField(prefix, nlriByteBuf);
         }
         buffer.writeBytes(nlriByteBuf);
     }
 
-    @Override
-    public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder) throws BGPParsingException {
-        if (!nlri.isReadable()) {
-            return;
-        }
-        final List<VpnIpv4Destination> dst = parseNlri(nlri, builder.getAfi());
-
-        builder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
-            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv4CaseBuilder().setDestinationVpnIpv4(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.vpn.ipv4._case.DestinationVpnIpv4Builder().setVpnIpv4Destination(
-                    dst).build()).build()).build());
-    }
-
-    @Override
-    public void parseNlri(final ByteBuf nlri, final MpReachNlriBuilder builder) throws BGPParsingException {
-        if (!nlri.isReadable()) {
-            return;
-        }
-        final List<VpnIpv4Destination> dst = parseNlri(nlri, builder.getAfi());
-
-        builder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
-            new DestinationVpnIpv4CaseBuilder().setDestinationVpnIpv4(
-                new DestinationVpnIpv4Builder().setVpnIpv4Destination(
-                    dst).build()).build()).build());
-    }
-
-    private static List<VpnIpv4Destination> parseNlri(final ByteBuf nlri, final Class<? extends AddressFamily> afi) {
+    private static List<VpnDestination> parseNlri(final ByteBuf nlri, final Class<? extends AddressFamily> afi) {
         if (!nlri.isReadable()) {
             return null;
         }
-        final List<VpnIpv4Destination> dests = new ArrayList<>();
+        final List<VpnDestination> dests = new ArrayList<>();
 
         while (nlri.isReadable()) {
-            final VpnIpv4DestinationBuilder builder = new VpnIpv4DestinationBuilder();
+            final VpnDestinationBuilder builder = new VpnDestinationBuilder();
             final short length = nlri.readUnsignedByte();
             builder.setLabelStack(LUNlriParser.parseLabel(nlri));
             final int labelNum = builder.getLabelStack().size();
             final int prefixLen = length - (LUNlriParser.LABEL_LENGTH * Byte.SIZE * labelNum) - (RouteDistinguisherUtil.RD_LENGTH * Byte.SIZE);
             builder.setRouteDistinguisher(RouteDistinguisherUtil.parseRouteDistinguisher(nlri));
-            Preconditions.checkState(prefixLen > 0, "VPN IPv4 is required.");
+            Preconditions.checkState(prefixLen > 0, "A valid VPN IP prefix is required.");
             builder.setPrefix(LUNlriParser.parseIpPrefix(nlri, prefixLen, afi));
             dests.add(builder.build());
         }
         return dests;
     }
 
+    @Override
+    public void serializeAttribute(final DataObject attribute, final ByteBuf byteAggregator) {
+        Preconditions.checkArgument(attribute instanceof Attributes, "Attribute parameter is not a Attributes object");
+        final Attributes pathAttributes = (Attributes) attribute;
+        final Attributes1 pathAttributes1 = pathAttributes.getAugmentation(Attributes1.class);
+        final Attributes2 pathAttributes2 = pathAttributes.getAugmentation(Attributes2.class);
+        List<VpnDestination> vpnDst = null;
+        if (pathAttributes1 != null) {
+            final AdvertizedRoutes routes = (pathAttributes1.getMpReachNlri()).getAdvertizedRoutes();
+            if (routes != null) {
+                vpnDst = getAdvertizedVpnDestination(routes.getDestinationType());
+            }
+        } else if (pathAttributes2 != null) {
+            final WithdrawnRoutes routes = pathAttributes2.getMpUnreachNlri().getWithdrawnRoutes();
+            if (routes != null) {
+                vpnDst = getWithdrawnVpnDestination(routes.getDestinationType());
+            }
+        }
+        if (vpnDst != null)
+            serializeNlri(vpnDst, byteAggregator);
+    }
+
+    @Override
+    public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder) throws BGPParsingException {
+        if (!nlri.isReadable()) {
+            return;
+        }
+        final List<VpnDestination> dst = parseNlri(nlri, builder.getAfi());
+        builder.setWithdrawnRoutes(getWithdrawnRoutesByDestination(dst));
+    }
+
+    @Override
+    public void parseNlri(final ByteBuf nlri, final MpReachNlriBuilder builder) throws BGPParsingException {
+        if (!nlri.isReadable()) {
+            return;
+        }
+        final List<VpnDestination> dst = parseNlri(nlri, builder.getAfi());
+        builder.setAdvertizedRoutes(getAdvertizedRoutesByDestination(dst));
+    }
 }
diff --git a/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/AbstractVpnRIBSupport.java b/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/AbstractVpnRIBSupport.java
new file mode 100644 (file)
index 0000000..865e27d
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.l3vpn;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableSet;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.protocol.bgp.labeled.unicast.LabeledUnicastRIBSupport;
+import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupport;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisher;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisherBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestinationBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Kevin Wang
+ */
+public abstract class AbstractVpnRIBSupport extends AbstractRIBSupport {
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractVpnRIBSupport.class);
+    private static final ApplyRoute DELETE_ROUTE = new DeleteRoute();
+    private final NodeIdentifier NLRI_ROUTES_LIST;
+    private final NodeIdentifier PREFIX_TYPE_NID;
+    private final NodeIdentifier LABEL_STACK_NID;
+    private final NodeIdentifier LV_NID;
+    private final NodeIdentifier RD_NID;
+    private final NodeIdentifier DESTINATION;
+    private final QName ROUTE_KEY;
+    private final NodeIdentifier ROUTE;
+    private final ApplyRoute PUT_ROUTE = new PutRoute();
+    private final Class<? extends AddressFamily> ADDRESS_FAMILY_CLAZZ;
+    private final QName CONTAINER_CLASS_QNAME;
+    private final QName LIST_CLASS_QNAME;
+    private final ChoiceNode EMPTY_ROUTES;
+
+    /**
+     * Default constructor. Requires the QName of the container augmented under the routes choice
+     * node in instantiations of the rib grouping. It is assumed that this container is defined by
+     * the same model which populates it with route grouping instantiation, and by extension with
+     * the route attributes container.
+     *
+     * @param cazeClass      Binding class of the AFI/SAFI-specific case statement, must not be null
+     * @param containerClass Binding class of the container in routes choice, must not be null.
+     * @param listClass      Binding class of the route list, nust not be null;
+     */
+    protected AbstractVpnRIBSupport(
+        Class<? extends Routes> cazeClass,
+        Class<? extends DataObject> containerClass,
+        Class<? extends Route> listClass,
+        Class<? extends AddressFamily> addressFamilyClass,
+        final QName VPN_DST_CONTAINER_CLASS_QNAME
+    ) {
+        super(cazeClass, containerClass, listClass);
+        CONTAINER_CLASS_QNAME = BindingReflections.findQName(containerClass).intern();
+        LIST_CLASS_QNAME =
+            QName.create(
+                CONTAINER_CLASS_QNAME.getNamespace(), CONTAINER_CLASS_QNAME.getRevision(), BindingReflections.findQName(listClass).intern().getLocalName()
+            );
+        ROUTE = NodeIdentifier.create(LIST_CLASS_QNAME);
+        ROUTE_KEY = QName.create(LIST_CLASS_QNAME, "route-key").intern();
+        EMPTY_ROUTES = Builders.choiceBuilder()
+            .withNodeIdentifier(YangInstanceIdentifier.NodeIdentifier.create(Routes.QNAME))
+            .addChild(
+                Builders.containerBuilder()
+                    .withNodeIdentifier(YangInstanceIdentifier.NodeIdentifier.create(CONTAINER_CLASS_QNAME))
+                    .addChild(
+                        ImmutableNodes.mapNodeBuilder(
+                            LIST_CLASS_QNAME
+                        ).build()
+                    ).build()
+            ).build();
+        final QName VPN_DST_CLASS_QNAME =
+            QName.create(
+                CONTAINER_CLASS_QNAME.getNamespace(), CONTAINER_CLASS_QNAME.getRevision(), VpnDestination.QNAME.getLocalName()
+            );
+        NLRI_ROUTES_LIST = NodeIdentifier.create(VPN_DST_CLASS_QNAME);
+        PREFIX_TYPE_NID = NodeIdentifier.create(QName.create(VPN_DST_CLASS_QNAME, "prefix").intern());
+        LABEL_STACK_NID = NodeIdentifier.create(QName.create(VPN_DST_CLASS_QNAME, "label-stack").intern());
+        LV_NID = NodeIdentifier.create(QName.create(VPN_DST_CLASS_QNAME, "label-value").intern());
+        RD_NID = NodeIdentifier.create(QName.create(VPN_DST_CLASS_QNAME, "route-distinguisher").intern());
+        DESTINATION = NodeIdentifier.create(VPN_DST_CONTAINER_CLASS_QNAME);
+        ADDRESS_FAMILY_CLAZZ = addressFamilyClass;
+    }
+
+    private VpnDestination extractVpnDestination(DataContainerNode<? extends PathArgument> route) {
+        final VpnDestination dst = new VpnDestinationBuilder()
+            .setPrefix(LabeledUnicastRIBSupport.extractPrefix(route, PREFIX_TYPE_NID))
+            .setLabelStack(LabeledUnicastRIBSupport.extractLabel(route, LABEL_STACK_NID, LV_NID))
+            .setRouteDistinguisher(extractRouteDistinguisher(route))
+            .build();
+        return dst;
+    }
+
+    private RouteDistinguisher extractRouteDistinguisher(final DataContainerNode<? extends YangInstanceIdentifier.PathArgument> route) {
+        if (route.getChild(RD_NID).isPresent()) {
+            return RouteDistinguisherBuilder.getDefaultInstance((String) route.getChild(RD_NID).get().getValue());
+        }
+        return null;
+    }
+
+    @Nonnull
+    @Override
+    public ChoiceNode emptyRoutes() {
+        return EMPTY_ROUTES;
+    }
+
+    @Nonnull
+    @Override
+    protected NodeIdentifier destinationContainerIdentifier() {
+        return DESTINATION;
+    }
+
+    @Override
+    protected void deleteDestinationRoutes(DOMDataWriteTransaction tx, YangInstanceIdentifier tablePath, ContainerNode destination, YangInstanceIdentifier.NodeIdentifier routesNodeId) {
+        processDestination(tx, tablePath.node(routesNodeId), destination, null, DELETE_ROUTE);
+    }
+
+    @Override
+    protected void putDestinationRoutes(DOMDataWriteTransaction tx, YangInstanceIdentifier tablePath, ContainerNode destination, ContainerNode attributes, YangInstanceIdentifier.NodeIdentifier routesNodeId) {
+        processDestination(tx, tablePath.node(routesNodeId), destination, attributes, PUT_ROUTE);
+    }
+
+    protected abstract DestinationType getAdvertizedDestinationType(List<VpnDestination> dests);
+
+    protected abstract DestinationType getWithdrawnDestinationType(List<VpnDestination> dests);
+
+    @Nonnull
+    @Override
+    protected MpReachNlri buildReach(Collection<MapEntryNode> routes, CNextHop hop) {
+        final MpReachNlriBuilder mb = new MpReachNlriBuilder()
+            .setAfi(ADDRESS_FAMILY_CLAZZ)
+            .setSafi(MplsLabeledVpnSubsequentAddressFamily.class)
+            .setCNextHop(hop);
+
+        final List<VpnDestination> dests = new ArrayList<>(routes.size());
+        dests.addAll(routes.stream().map(this::extractVpnDestination).collect(Collectors.toList()));
+
+        mb.setAdvertizedRoutes(
+            new AdvertizedRoutesBuilder().setDestinationType(
+                getAdvertizedDestinationType(dests)
+            ).build()
+        ).build();
+        return mb.build();
+    }
+
+    @Nonnull
+    @Override
+    protected MpUnreachNlri buildUnreach(Collection<MapEntryNode> routes) {
+        final MpUnreachNlriBuilder mb = new MpUnreachNlriBuilder()
+            .setAfi(ADDRESS_FAMILY_CLAZZ)
+            .setSafi(MplsLabeledVpnSubsequentAddressFamily.class);
+
+        final List<VpnDestination> dests = new ArrayList<>(routes.size());
+        dests.addAll(routes.stream().map(this::extractVpnDestination).collect(Collectors.toList()));
+
+        mb.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
+            getWithdrawnDestinationType(dests)
+            ).build()
+        ).build();
+        return mb.build();
+    }
+
+    @Nonnull
+    @Override
+    public ImmutableCollection<Class<? extends DataObject>> cacheableAttributeObjects() {
+        return ImmutableSet.of();
+    }
+
+    @Nonnull
+    @Override
+    public ImmutableCollection<Class<? extends DataObject>> cacheableNlriObjects() {
+        return ImmutableSet.of();
+    }
+
+    @Override
+    public boolean isComplexRoute() {
+        return true;
+    }
+
+    private void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
+                                    final ContainerNode destination, final ContainerNode attributes, final ApplyRoute function) {
+        if (destination != null) {
+            final Optional<DataContainerChild<? extends PathArgument, ?>> maybeRoutes = destination.getChild(NLRI_ROUTES_LIST);
+            if (maybeRoutes.isPresent()) {
+                final DataContainerChild<? extends PathArgument, ?> routes = maybeRoutes.get();
+                if (routes instanceof UnkeyedListNode) {
+                    UnkeyedListNode routeListNode = (UnkeyedListNode) routes;
+                    LOG.debug("{} routes are found", routeListNode.getSize());
+                    final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(ROUTE);
+                    for (final UnkeyedListEntryNode e : routeListNode.getValue()) {
+                        final NodeIdentifierWithPredicates routeKey = createRouteKey(e);
+                        LOG.debug("Route {} is processed.", routeKey);
+                        function.apply(tx, base, routeKey, e, attributes);
+                    }
+                } else {
+                    LOG.warn("Routes {} are not a map", routes);
+                }
+            }
+        } else {
+            LOG.debug("Destination is null.");
+        }
+    }
+
+    private NodeIdentifierWithPredicates createRouteKey(final UnkeyedListEntryNode l3vpn) {
+        final ByteBuf buffer = Unpooled.buffer();
+
+        final VpnDestination dest = extractVpnDestination(l3vpn);
+        AbstractVpnNlriParser.serializeNlri(Collections.singletonList(dest), buffer);
+        return new NodeIdentifierWithPredicates(LIST_CLASS_QNAME, ROUTE_KEY, ByteArray.readAllBytes(buffer));
+    }
+
+    private abstract static class ApplyRoute {
+        abstract void apply(DOMDataWriteTransaction tx, YangInstanceIdentifier base, YangInstanceIdentifier.NodeIdentifierWithPredicates routeKey, DataContainerNode<?> route, final ContainerNode attributes);
+    }
+
+    private static final class DeleteRoute extends ApplyRoute {
+        @Override
+        void apply(final DOMDataWriteTransaction tx, final YangInstanceIdentifier base,
+                   final NodeIdentifierWithPredicates routeKey,
+                   final DataContainerNode<?> route, final ContainerNode attributes) {
+            tx.delete(LogicalDatastoreType.OPERATIONAL, base.node(routeKey));
+        }
+    }
+
+    private final class PutRoute extends ApplyRoute {
+        @Override
+        void apply(final DOMDataWriteTransaction tx, final YangInstanceIdentifier base,
+                   final NodeIdentifierWithPredicates routeKey,
+                   final DataContainerNode<?> route, final ContainerNode attributes) {
+            // Build the DataContainer data
+            final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> b = ImmutableNodes.mapEntryBuilder();
+            b.withNodeIdentifier(routeKey);
+
+            route.getValue().forEach(b::withChild);
+            // Add attributes
+            final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> cb = Builders.containerBuilder(attributes);
+            cb.withNodeIdentifier(routeAttributesIdentifier());
+            b.withChild(cb.build());
+            tx.put(LogicalDatastoreType.OPERATIONAL, base.node(routeKey), b.build());
+        }
+    }
+}
diff --git a/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/VpnIpv4RIBSupport.java b/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/VpnIpv4RIBSupport.java
deleted file mode 100644 (file)
index ae71776..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.protocol.bgp.l3vpn;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableSet;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.protocol.bgp.labeled.unicast.LabeledUnicastRIBSupport;
-import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupport;
-import org.opendaylight.protocol.util.ByteArray;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisherBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.bgp.rib.rib.loc.rib.tables.routes.VpnIpv4RoutesCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv4CaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.vpn.ipv4._case.DestinationVpnIpv4;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.vpn.ipv4._case.DestinationVpnIpv4Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.vpn.ipv4.destination.VpnIpv4Destination;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.vpn.ipv4.destination.VpnIpv4DestinationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.vpn.ipv4.routes.VpnIpv4Routes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.vpn.ipv4.routes.vpn.ipv4.routes.VpnIpv4Route;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class VpnIpv4RIBSupport extends AbstractRIBSupport {
-
-    private static final Logger LOG = LoggerFactory.getLogger(VpnIpv4RIBSupport.class);
-
-    private static final ApplyRoute DELETE_ROUTE = new DeleteRoute();
-
-    private static final ChoiceNode EMPTY_ROUTES = Builders.choiceBuilder()
-        .withNodeIdentifier(NodeIdentifier.create(Routes.QNAME))
-        .addChild(Builders.containerBuilder()
-            .withNodeIdentifier(NodeIdentifier.create(VpnIpv4Routes.QNAME))
-            .addChild(ImmutableNodes.mapNodeBuilder(VpnIpv4Route.QNAME).build()).build()).build();
-    private static final NodeIdentifier DESTINATION = NodeIdentifier.create(DestinationVpnIpv4.QNAME);
-    private static final NodeIdentifier NLRI_ROUTES_LIST = NodeIdentifier.create(VpnIpv4Destination.QNAME);
-    private static final NodeIdentifier ROUTE = NodeIdentifier.create(VpnIpv4Route.QNAME);
-    private static final NodeIdentifier PREFIX_TYPE_NID = NodeIdentifier.create(QName.create(VpnIpv4Destination.QNAME, "prefix").intern());
-    private static final NodeIdentifier LABEL_STACK_NID = NodeIdentifier.create(QName.create(VpnIpv4Destination.QNAME, "label-stack").intern());
-    private static final NodeIdentifier LV_NID = NodeIdentifier.create(QName.create(VpnIpv4Destination.QNAME, "label-value").intern());
-    private static final QName ROUTE_KEY = QName.create(VpnIpv4Route.QNAME, "route-key").intern();
-
-    private static final NodeIdentifier RD_NID = NodeIdentifier.create(QName.create(VpnIpv4Destination.QNAME, "route-distinguisher").intern());;
-
-    protected VpnIpv4RIBSupport() {
-        super(VpnIpv4RoutesCase.class, VpnIpv4Routes.class, VpnIpv4Route.class);
-    }
-
-    private final ApplyRoute putRoute = new PutRoute();
-
-    private abstract static class ApplyRoute {
-        abstract void apply(DOMDataWriteTransaction tx, YangInstanceIdentifier base, NodeIdentifierWithPredicates routeKey, DataContainerNode<?> route, final ContainerNode attributes);
-    }
-
-    private static final class DeleteRoute extends ApplyRoute {
-        @Override
-        void apply(final DOMDataWriteTransaction tx, final YangInstanceIdentifier base,
-            final NodeIdentifierWithPredicates routeKey,
-            final DataContainerNode<?> route, final ContainerNode attributes) {
-            tx.delete(LogicalDatastoreType.OPERATIONAL, base.node(routeKey));
-        }
-    }
-
-    private final class PutRoute extends ApplyRoute {
-        @Override
-        void apply(final DOMDataWriteTransaction tx, final YangInstanceIdentifier base,
-            final NodeIdentifierWithPredicates routeKey,
-            final DataContainerNode<?> route, final ContainerNode attributes) {
-            // Build the DataContainer data
-            final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> b = ImmutableNodes.mapEntryBuilder();
-            b.withNodeIdentifier(routeKey);
-
-            for (final DataContainerChild<? extends PathArgument, ?> child : route.getValue()) {
-                b.withChild(child);
-            }
-            // Add attributes
-            final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> cb = Builders.containerBuilder(attributes);
-            cb.withNodeIdentifier(routeAttributesIdentifier());
-            b.withChild(cb.build());
-            tx.put(LogicalDatastoreType.OPERATIONAL, base.node(routeKey), b.build());
-        }
-    }
-
-    @Override
-    public ChoiceNode emptyRoutes() {
-        return EMPTY_ROUTES;
-    }
-
-    @Override
-    public ImmutableCollection<Class<? extends DataObject>> cacheableAttributeObjects() {
-        return ImmutableSet.of();
-    }
-
-    @Override
-    public ImmutableCollection<Class<? extends DataObject>> cacheableNlriObjects() {
-        return ImmutableSet.of();
-    }
-
-    @Override
-    public boolean isComplexRoute() {
-        return true;
-    }
-
-    @Override
-    protected NodeIdentifier destinationContainerIdentifier() {
-        return DESTINATION;
-    }
-
-    private void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
-        final ContainerNode destination, final ContainerNode attributes, final ApplyRoute function) {
-        if (destination != null) {
-            final Optional<DataContainerChild<? extends PathArgument, ?>> maybeRoutes = destination.getChild(NLRI_ROUTES_LIST);
-            if (maybeRoutes.isPresent()) {
-                final DataContainerChild<? extends PathArgument, ?> routes = maybeRoutes.get();
-                if (routes instanceof UnkeyedListNode) {
-                    final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(ROUTE);
-                    for (final UnkeyedListEntryNode e : ((UnkeyedListNode)routes).getValue()) {
-                        final NodeIdentifierWithPredicates routeKey = createRouteKey(e);
-                        function.apply(tx, base, routeKey, e, attributes);
-                    }
-                } else {
-                    LOG.warn("Routes {} are not a map", routes);
-                }
-            }
-        }
-    }
-
-    private NodeIdentifierWithPredicates createRouteKey(final UnkeyedListEntryNode l3vpn) {
-        final ByteBuf buffer = Unpooled.buffer();
-
-        final VpnIpv4Destination dest = extractVpnIpv4Destination(l3vpn);
-        VpnIpv4NlriParser.serializeNlri(Collections.singletonList(dest), buffer);
-        return new NodeIdentifierWithPredicates(VpnIpv4Route.QNAME, ROUTE_KEY, ByteArray.readAllBytes(buffer));
-    }
-
-    @Override
-    protected void deleteDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath,
-        final ContainerNode destination, final NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, null, DELETE_ROUTE);
-    }
-
-    @Override
-    protected void putDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath,
-        final ContainerNode destination, final ContainerNode attributes, final NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, attributes, this.putRoute);
-    }
-
-    @Override
-    protected MpReachNlri buildReach(final Collection<MapEntryNode> routes, final CNextHop hop) {
-        final MpReachNlriBuilder mb = new MpReachNlriBuilder();
-        mb.setAfi(Ipv4AddressFamily.class);
-        mb.setSafi(MplsLabeledVpnSubsequentAddressFamily.class);
-        mb.setCNextHop(hop);
-
-        final List<VpnIpv4Destination> dests = new ArrayList<>(routes.size());
-        for (final MapEntryNode route : routes) {
-            dests.add(extractVpnIpv4Destination(route));
-        }
-        mb.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
-            new DestinationVpnIpv4CaseBuilder().setDestinationVpnIpv4(
-                new DestinationVpnIpv4Builder().setVpnIpv4Destination(dests).build()).build()).build());
-        return mb.build();
-    }
-
-    @Override
-    protected MpUnreachNlri buildUnreach(final Collection<MapEntryNode> routes) {
-        final MpUnreachNlriBuilder mb = new MpUnreachNlriBuilder();
-        mb.setAfi(Ipv4AddressFamily.class);
-        mb.setSafi(MplsLabeledVpnSubsequentAddressFamily.class);
-
-        final List<VpnIpv4Destination> dests = new ArrayList<>(routes.size());
-        for (final MapEntryNode route : routes) {
-            dests.add(extractVpnIpv4Destination(route));
-        }
-        mb.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
-            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv4CaseBuilder().setDestinationVpnIpv4(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.vpn.ipv4._case.DestinationVpnIpv4Builder().setVpnIpv4Destination(dests).build()).build()).build());
-        return mb.build();
-    }
-
-    private static VpnIpv4Destination extractVpnIpv4Destination(final DataContainerNode<? extends PathArgument> route) {
-        final VpnIpv4DestinationBuilder builder = new VpnIpv4DestinationBuilder();
-        builder.setPrefix(LabeledUnicastRIBSupport.extractPrefix(route, PREFIX_TYPE_NID));
-        builder.setLabelStack(LabeledUnicastRIBSupport.extractLabel(route, LABEL_STACK_NID, LV_NID));
-        builder.setRouteDistinguisher(extractRouteDistinguisher(route));
-        return builder.build();
-    }
-
-    private static RouteDistinguisher extractRouteDistinguisher(final DataContainerNode<? extends PathArgument> route) {
-        if (route.getChild(RD_NID).isPresent()) {
-            return RouteDistinguisherBuilder.getDefaultInstance((String) route.getChild(RD_NID).get().getValue());
-        }
-        return null;
-    }
-}
similarity index 88%
rename from bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/BGPActivator.java
rename to bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/BgpIpv4Activator.java
index 8b478139e0e4c13d206f886e0e2c3af16dacd7ce..9921dec3b5f2c540d03f3fdfd54336f805d11154 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.protocol.bgp.l3vpn;
+package org.opendaylight.protocol.bgp.l3vpn.ipv4;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -14,9 +14,9 @@ import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.vpn.ipv4.routes.VpnIpv4Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.l3vpn.ipv4.routes.VpnIpv4Routes;
 
-public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
+public final class BgpIpv4Activator extends AbstractBGPExtensionProviderActivator {
 
     @Override
     protected List<AutoCloseable> startImpl(final BGPExtensionProviderContext context) {
similarity index 89%
rename from bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/RIBActivator.java
rename to bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/RibIpv4Activator.java
index ae68ddf095b6ee8d44a90fe8fc7c88c58b7233a1..c8876c1155a71f1e8667b9526c28f931c3fcf725 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.protocol.bgp.l3vpn;
+package org.opendaylight.protocol.bgp.l3vpn.ipv4;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -14,7 +14,7 @@ import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
 
-public class RIBActivator extends AbstractRIBExtensionProviderActivator {
+public class RibIpv4Activator extends AbstractRIBExtensionProviderActivator {
 
     @Override
     protected List<AutoCloseable> startRIBExtensionProviderImpl(final RIBExtensionProviderContext context) {
diff --git a/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4NextHopParserSerializer.java b/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4NextHopParserSerializer.java
new file mode 100644 (file)
index 0000000..493f23c
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.l3vpn.ipv4;
+
+import org.opendaylight.protocol.bgp.l3vpn.AbstractVpnNextHopParserSerializer;
+import org.opendaylight.protocol.util.Ipv4Util;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
+
+public final class VpnIpv4NextHopParserSerializer extends AbstractVpnNextHopParserSerializer {
+    public VpnIpv4NextHopParserSerializer() {
+        super(Ipv4Util.IP4_LENGTH, Ipv4NextHopCase.class);
+    }
+}
diff --git a/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4NlriParser.java b/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4NlriParser.java
new file mode 100644 (file)
index 0000000..21e8295
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.l3vpn.ipv4;
+
+import java.util.List;
+import org.opendaylight.protocol.bgp.l3vpn.AbstractVpnNlriParser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.L3vpnIpv4Destination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.l3vpn.ipv4.destination.VpnIpv4DestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestination;
+
+public class VpnIpv4NlriParser extends AbstractVpnNlriParser {
+
+    private <T extends L3vpnIpv4Destination> List<VpnDestination> getVpnDestination(DestinationType dst, Class<T> dstTypeCaseClazz) {
+        if (dstTypeCaseClazz.isInstance(dst))
+            return dstTypeCaseClazz.cast(dst).getVpnIpv4Destination().getVpnDestination();
+        else
+            return null;
+    }
+
+    @Override
+    protected List<VpnDestination> getWithdrawnVpnDestination(DestinationType dstType) {
+        return getVpnDestination(dstType, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv4Case.class);
+    }
+
+    @Override
+    protected List<VpnDestination> getAdvertizedVpnDestination(DestinationType dstType) {
+        return getVpnDestination(dstType, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv4Case.class);
+    }
+
+    @Override
+    protected WithdrawnRoutes getWithdrawnRoutesByDestination(List<VpnDestination> dst) {
+        return new WithdrawnRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv4CaseBuilder().setVpnIpv4Destination(
+                new VpnIpv4DestinationBuilder().setVpnDestination(dst).build()
+            ).build()
+        ).build();
+    }
+
+    @Override
+    protected AdvertizedRoutes getAdvertizedRoutesByDestination(List<VpnDestination> dst) {
+        return new AdvertizedRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv4CaseBuilder().setVpnIpv4Destination(
+                new VpnIpv4DestinationBuilder().setVpnDestination(dst).build()
+            ).build()
+        ).build();
+    }
+}
diff --git a/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4RIBSupport.java b/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4RIBSupport.java
new file mode 100644 (file)
index 0000000..c647f35
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.l3vpn.ipv4;
+
+import java.util.List;
+import org.opendaylight.protocol.bgp.l3vpn.AbstractVpnRIBSupport;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.bgp.rib.rib.loc.rib.tables.routes.VpnIpv4RoutesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.l3vpn.ipv4.destination.VpnIpv4Destination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.l3vpn.ipv4.destination.VpnIpv4DestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.l3vpn.ipv4.routes.VpnIpv4Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.route.VpnRoute;
+
+final class VpnIpv4RIBSupport extends AbstractVpnRIBSupport {
+    /**
+     * Default constructor. Requires the QName of the container augmented under the routes choice
+     * node in instantiations of the rib grouping. It is assumed that this container is defined by
+     * the same model which populates it with route grouping instantiation, and by extension with
+     * the route attributes container.
+     */
+    public VpnIpv4RIBSupport() {
+        super(VpnIpv4RoutesCase.class, VpnIpv4Routes.class, VpnRoute.class, Ipv4AddressFamily.class, VpnIpv4Destination.QNAME);
+    }
+
+    @Override
+    protected DestinationType getAdvertizedDestinationType(List<VpnDestination> dests) {
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv4CaseBuilder().setVpnIpv4Destination(
+            new VpnIpv4DestinationBuilder().setVpnDestination(dests).build()
+        ).build();
+    }
+
+    @Override
+    protected DestinationType getWithdrawnDestinationType(List<VpnDestination> dests) {
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv4CaseBuilder().setVpnIpv4Destination(
+            new VpnIpv4DestinationBuilder().setVpnDestination(dests).build()
+        ).build();
+    }
+}
diff --git a/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/BgpIpv6Activator.java b/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/BgpIpv6Activator.java
new file mode 100644 (file)
index 0000000..0c88e9a
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.l3vpn.ipv6;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.protocol.bgp.parser.spi.AbstractBGPExtensionProviderActivator;
+import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.l3vpn.ipv6.routes.VpnIpv6Routes;
+
+/**
+ * @author Kevin Wang
+ */
+public final class BgpIpv6Activator extends AbstractBGPExtensionProviderActivator {
+
+    @Override
+    protected List<AutoCloseable> startImpl(final BGPExtensionProviderContext context) {
+        final List<AutoCloseable> regs = new ArrayList<>();
+
+        final VpnIpv6NlriParser nlriParser = new VpnIpv6NlriParser();
+        final VpnIpv6NextHopParserSerializer nextHopParser = new VpnIpv6NextHopParserSerializer();
+
+        regs.add(context.registerNlriParser(Ipv6AddressFamily.class, MplsLabeledVpnSubsequentAddressFamily.class,
+            nlriParser, nextHopParser, Ipv6NextHopCase.class));
+        regs.add(context.registerNlriSerializer(VpnIpv6Routes.class, nlriParser));
+
+        return regs;
+    }
+
+}
diff --git a/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/RibIpv6Activator.java b/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/RibIpv6Activator.java
new file mode 100644 (file)
index 0000000..d5f7667
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.l3vpn.ipv6;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBExtensionProviderActivator;
+import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
+
+/**
+ * @author Kevin Wang
+ */
+public class RibIpv6Activator extends AbstractRIBExtensionProviderActivator {
+
+    @Override
+    protected List<AutoCloseable> startRIBExtensionProviderImpl(final RIBExtensionProviderContext context) {
+        final List<AutoCloseable> regs = new ArrayList<>();
+        regs.add(context.registerRIBSupport(Ipv6AddressFamily.class, MplsLabeledVpnSubsequentAddressFamily.class, new VpnIpv6RIBSupport()));
+        return regs;
+    }
+
+}
diff --git a/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6NextHopParserSerializer.java b/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6NextHopParserSerializer.java
new file mode 100644 (file)
index 0000000..cc6a699
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.l3vpn.ipv6;
+
+import org.opendaylight.protocol.bgp.l3vpn.AbstractVpnNextHopParserSerializer;
+import org.opendaylight.protocol.util.Ipv6Util;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase;
+
+/**
+ * @author Kevin Wang
+ */
+public final class VpnIpv6NextHopParserSerializer extends AbstractVpnNextHopParserSerializer {
+    public VpnIpv6NextHopParserSerializer() {
+        super(Ipv6Util.IPV6_LENGTH, Ipv6NextHopCase.class);
+    }
+}
diff --git a/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6NlriParser.java b/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6NlriParser.java
new file mode 100644 (file)
index 0000000..da999a8
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.l3vpn.ipv6;
+
+import java.util.List;
+import org.opendaylight.protocol.bgp.l3vpn.AbstractVpnNlriParser;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.L3vpnIpv6Destination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.l3vpn.ipv6.destination.VpnIpv6DestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestination;
+
+/**
+ * @author Kevin Wang
+ */
+public class VpnIpv6NlriParser extends AbstractVpnNlriParser {
+
+    private <T extends L3vpnIpv6Destination> List<VpnDestination> getVpnDestination(DestinationType dst, Class<T> dstTypeCaseClazz) {
+        if (dstTypeCaseClazz.isInstance(dst))
+            return dstTypeCaseClazz.cast(dst).getVpnIpv6Destination().getVpnDestination();
+        else
+            return null;
+    }
+
+    @Override
+    protected List<VpnDestination> getWithdrawnVpnDestination(DestinationType dstType) {
+        return getVpnDestination(
+            dstType,
+            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv6Case.class);
+    }
+
+    @Override
+    protected List<VpnDestination> getAdvertizedVpnDestination(DestinationType dstType) {
+        return getVpnDestination(
+            dstType,
+            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv6Case.class
+        );
+    }
+
+    @Override
+    protected WithdrawnRoutes getWithdrawnRoutesByDestination(List<VpnDestination> dst) {
+        return new WithdrawnRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv6CaseBuilder().setVpnIpv6Destination(
+                new VpnIpv6DestinationBuilder().setVpnDestination(dst).build()
+            ).build()
+        ).build();
+    }
+
+    @Override
+    protected AdvertizedRoutes getAdvertizedRoutesByDestination(List<VpnDestination> dst) {
+        return new AdvertizedRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv6CaseBuilder().setVpnIpv6Destination(
+                new VpnIpv6DestinationBuilder().setVpnDestination(dst).build()
+            ).build()
+        ).build();
+    }
+
+}
diff --git a/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6RIBSupport.java b/bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6RIBSupport.java
new file mode 100644 (file)
index 0000000..316ac54
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.l3vpn.ipv6;
+
+import java.util.List;
+import org.opendaylight.protocol.bgp.l3vpn.AbstractVpnRIBSupport;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.bgp.rib.rib.loc.rib.tables.routes.VpnIpv6RoutesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.l3vpn.ipv6.destination.VpnIpv6Destination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.l3vpn.ipv6.destination.VpnIpv6DestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.l3vpn.ipv6.routes.VpnIpv6Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.route.VpnRoute;
+
+/**
+ * @author Kevin Wang
+ */
+final class VpnIpv6RIBSupport extends AbstractVpnRIBSupport {
+
+    /**
+     * Default constructor. Requires the QName of the container augmented under the routes choice
+     * node in instantiations of the rib grouping. It is assumed that this container is defined by
+     * the same model which populates it with route grouping instantiation, and by extension with
+     * the route attributes container.
+     */
+    public VpnIpv6RIBSupport() {
+        super(VpnIpv6RoutesCase.class, VpnIpv6Routes.class, VpnRoute.class, Ipv6AddressFamily.class, VpnIpv6Destination.QNAME);
+    }
+
+    @Override
+    protected DestinationType getAdvertizedDestinationType(List<VpnDestination> dests) {
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv6CaseBuilder().setVpnIpv6Destination(
+            new VpnIpv6DestinationBuilder().setVpnDestination(dests).build()
+        ).build();
+    }
+
+    @Override
+    protected DestinationType getWithdrawnDestinationType(List<VpnDestination> dests) {
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv6CaseBuilder().setVpnIpv6Destination(
+            new VpnIpv6DestinationBuilder().setVpnDestination(dests).build()
+        ).build();
+    }
+}
index d8e17f823a56956e1e12c9cd26410b896d127583..f29a3cf95d28e670e71256dc6de7f6bcedfc5143 100644 (file)
@@ -2,13 +2,11 @@ module bgp-vpn-ipv4 {
     namespace "urn:opendaylight:params:xml:ns:yang:bgp-vpn-ipv4";
     prefix "bgp-vpn";
 
-    import bgp-labeled-unicast { prefix bgp-lu; revision-date 2015-05-25; }
-    import bgp-types { prefix bgp-t; revision-date 2013-09-19; }
     import bgp-message { prefix bgp-msg; revision-date 2013-09-19; }
     import bgp-multiprotocol { prefix bgp-mp; revision-date 2013-09-19; }
-    import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
-    import bgp-rib { prefix bgp-rib; revision-date 2013-09-25; }
     import bmp-monitor { prefix bmp-mon; revision-date 2015-05-12; }
+    import bgp-rib { prefix bgp-rib; revision-date 2013-09-25; }
+    import bgp-vpn { prefix bgp-vpn; revision-date 2016-04-13; }
 
     organization "Cisco Systems, Inc.";
     contact "Iveta Halanova <ihalanov@cisco.com>";
@@ -25,91 +23,73 @@ module bgp-vpn-ipv4 {
         http://www.eclipse.org/legal/epl-v10.html";
 
     revision 2016-02-10 {
+        reference "https://tools.ietf.org/html/rfc4364";
         description "Initial revision";
     }
 
-    grouping vpn-ipv4 {
-        reference "https://tools.ietf.org/html/rfc4364#section-4.3.4";
-        uses bgp-lu:labeled-unicast;
-        leaf route-distinguisher {
-            type bgp-t:route-distinguisher;
-        }
-    }
-
-    grouping vpn-ipv4-destination {
-        list vpn-ipv4-destination {
-            uses vpn-ipv4;
+    grouping l3vpn-ipv4-routes {
+        container vpn-ipv4-routes {
+            uses bgp-vpn:l3vpn-ip-route;
         }
     }
 
-    grouping vpn-ipv4-routes {
-        container vpn-ipv4-routes {
-            list vpn-ipv4-route {
-                leaf route-key {
-                    type binary;
-                }
-                key "route-key";
-                uses vpn-ipv4;
-                uses bgp-rib:route;
-            }
+    grouping l3vpn-ipv4-destination {
+        container vpn-ipv4-destination {
+            uses bgp-vpn:l3vpn-ip-destination-type;
         }
     }
 
     augment "/bgp-msg:update/bgp-msg:attributes/bgp-mp:mp-reach-nlri/bgp-mp:advertized-routes/bgp-mp:destination-type" {
         case destination-vpn-ipv4-case {
-            container destination-vpn-ipv4 {
-                uses vpn-ipv4-destination;
-            }
+            uses l3vpn-ipv4-destination;
         }
     }
 
     augment "/bgp-msg:update/bgp-msg:attributes/bgp-mp:mp-unreach-nlri/bgp-mp:withdrawn-routes/bgp-mp:destination-type" {
         case destination-vpn-ipv4-case {
-            container destination-vpn-ipv4 {
-                uses vpn-ipv4-destination;
-            }
+            uses l3vpn-ipv4-destination;
         }
     }
 
     augment "/bgp-rib:application-rib/bgp-rib:tables/bgp-rib:routes" {
         case vpn-ipv4-routes-case {
-            uses vpn-ipv4-routes;
+            uses l3vpn-ipv4-routes;
         }
     }
 
     augment "/bgp-rib:bgp-rib/bgp-rib:rib/bgp-rib:loc-rib/bgp-rib:tables/bgp-rib:routes" {
         case vpn-ipv4-routes-case {
-            uses vpn-ipv4-routes;
+            uses l3vpn-ipv4-routes;
         }
     }
 
     augment "/bgp-rib:bgp-rib/bgp-rib:rib/bgp-rib:peer/bgp-rib:adj-rib-in/bgp-rib:tables/bgp-rib:routes" {
         case vpn-ipv4-routes-case {
-            uses vpn-ipv4-routes;
+            uses l3vpn-ipv4-routes;
         }
     }
 
     augment "/bgp-rib:bgp-rib/bgp-rib:rib/bgp-rib:peer/bgp-rib:effective-rib-in/bgp-rib:tables/bgp-rib:routes" {
         case vpn-ipv4-routes-case {
-            uses vpn-ipv4-routes;
+            uses l3vpn-ipv4-routes;
         }
     }
 
     augment "/bgp-rib:bgp-rib/bgp-rib:rib/bgp-rib:peer/bgp-rib:adj-rib-out/bgp-rib:tables/bgp-rib:routes" {
         case vpn-ipv4-routes-case {
-            uses vpn-ipv4-routes;
+            uses l3vpn-ipv4-routes;
         }
     }
 
     augment "/bmp-mon:bmp-monitor/bmp-mon:monitor/bmp-mon:router/bmp-mon:peer/bmp-mon:pre-policy-rib/bmp-mon:tables/bmp-mon:routes" {
         case vpn-ipv4-routes-case {
-            uses vpn-ipv4-routes;
+            uses l3vpn-ipv4-routes;
         }
     }
 
     augment "/bmp-mon:bmp-monitor/bmp-mon:monitor/bmp-mon:router/bmp-mon:peer/bmp-mon:post-policy-rib/bmp-mon:tables/bmp-mon:routes" {
         case vpn-ipv4-routes-case {
-            uses vpn-ipv4-routes;
+            uses l3vpn-ipv4-routes;
         }
     }
 }
\ No newline at end of file
diff --git a/bgp/l3vpn/src/main/yang/bgp-vpn-ipv6.yang b/bgp/l3vpn/src/main/yang/bgp-vpn-ipv6.yang
new file mode 100644 (file)
index 0000000..ac4edd8
--- /dev/null
@@ -0,0 +1,95 @@
+module bgp-vpn-ipv6 {
+    namespace "urn:opendaylight:params:xml:ns:yang:bgp-vpn-ipv6";
+    prefix "bgp-vpn";
+
+    import bgp-message { prefix bgp-msg; revision-date 2013-09-19; }
+    import bgp-multiprotocol { prefix bgp-mp; revision-date 2013-09-19; }
+    import bmp-monitor { prefix bmp-mon; revision-date 2015-05-12; }
+    import bgp-rib { prefix bgp-rib; revision-date 2013-09-25; }
+    import bgp-vpn { prefix bgp-vpn; revision-date 2016-04-13; }
+
+    organization "Brocade Communications Systems, Inc.";
+    contact "Kevin Wang <kwang@brocade.com>";
+
+    description
+        "This module contains the base data model of a BGP message.
+        It rolls up the definitions contained in RFC4659.
+
+        Copyright (c) 2016 Brocade Communications Systems, Inc. All rights reserved.
+
+        This program and the accompanying materials are made available
+        under the terms of the Eclipse Public License v1.0 which
+        accompanies this distribution, and is available at
+        http://www.eclipse.org/legal/epl-v10.html";
+
+    revision 2016-03-31 {
+        reference "https://tools.ietf.org/html/rfc4659";
+        description "Initial revision";
+    }
+
+    grouping l3vpn-ipv6-routes {
+        container vpn-ipv6-routes {
+            uses bgp-vpn:l3vpn-ip-route;
+        }
+    }
+
+    grouping l3vpn-ipv6-destination {
+        container vpn-ipv6-destination {
+            uses bgp-vpn:l3vpn-ip-destination-type;
+        }
+    }
+
+    augment "/bgp-msg:update/bgp-msg:attributes/bgp-mp:mp-reach-nlri/bgp-mp:advertized-routes/bgp-mp:destination-type" {
+        case destination-vpn-ipv6-case {
+            uses l3vpn-ipv6-destination;
+        }
+    }
+
+    augment "/bgp-msg:update/bgp-msg:attributes/bgp-mp:mp-unreach-nlri/bgp-mp:withdrawn-routes/bgp-mp:destination-type" {
+        case destination-vpn-ipv6-case {
+            uses l3vpn-ipv6-destination;
+        }
+    }
+
+    augment "/bgp-rib:application-rib/bgp-rib:tables/bgp-rib:routes" {
+        case routes-vpn-ipv6-case {
+            uses l3vpn-ipv6-routes;
+        }
+    }
+
+    augment "/bgp-rib:bgp-rib/bgp-rib:rib/bgp-rib:loc-rib/bgp-rib:tables/bgp-rib:routes" {
+        case vpn-ipv6-routes-case {
+            uses l3vpn-ipv6-routes;
+        }
+    }
+
+    augment "/bgp-rib:bgp-rib/bgp-rib:rib/bgp-rib:peer/bgp-rib:adj-rib-in/bgp-rib:tables/bgp-rib:routes" {
+        case vpn-ipv6-routes-case {
+            uses l3vpn-ipv6-routes;
+        }
+    }
+
+    augment "/bgp-rib:bgp-rib/bgp-rib:rib/bgp-rib:peer/bgp-rib:effective-rib-in/bgp-rib:tables/bgp-rib:routes" {
+        case vpn-ipv6-routes-case {
+            uses l3vpn-ipv6-routes;
+        }
+    }
+
+    augment "/bgp-rib:bgp-rib/bgp-rib:rib/bgp-rib:peer/bgp-rib:adj-rib-out/bgp-rib:tables/bgp-rib:routes" {
+        case vpn-ipv6-routes-case {
+            uses l3vpn-ipv6-routes;
+        }
+    }
+
+    augment "/bmp-mon:bmp-monitor/bmp-mon:monitor/bmp-mon:router/bmp-mon:peer/bmp-mon:pre-policy-rib/bmp-mon:tables/bmp-mon:routes" {
+        case vpn-ipv6-routes-case {
+            uses l3vpn-ipv6-routes;
+        }
+    }
+
+    augment "/bmp-mon:bmp-monitor/bmp-mon:monitor/bmp-mon:router/bmp-mon:peer/bmp-mon:post-policy-rib/bmp-mon:tables/bmp-mon:routes" {
+        case vpn-ipv6-routes-case {
+            uses l3vpn-ipv6-routes;
+        }
+    }
+}
\ No newline at end of file
diff --git a/bgp/l3vpn/src/main/yang/bgp-vpn.yang b/bgp/l3vpn/src/main/yang/bgp-vpn.yang
new file mode 100644 (file)
index 0000000..4b37117
--- /dev/null
@@ -0,0 +1,51 @@
+module bgp-vpn {
+    namespace "urn:opendaylight:params:xml:ns:yang:bgp-vpn";
+    prefix "bgp-vpn";
+
+    import bgp-labeled-unicast { prefix bgp-lu; revision-date 2015-05-25; }
+    import bgp-types { prefix bgp-t; revision-date 2013-09-19; }
+    import bgp-rib { prefix bgp-rib; revision-date 2013-09-25; }
+    import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
+
+    organization "Brocade Communications Systems, Inc.";
+    contact "Kevin Wang <kwang@brocade.com>";
+
+    description
+        "This module contains the base data model of a BGP message.
+        It defines the common part of both L3VPN-IPv4 and L3VPN-IPv6 model.
+
+        Copyright (c) 2016 Brocade Communications Systems, Inc. All rights reserved.
+
+        This program and the accompanying materials are made available
+        under the terms of the Eclipse Public License v1.0 which
+        accompanies this distribution, and is available at
+        http://www.eclipse.org/legal/epl-v10.html";
+
+    revision 2016-04-13 {
+        description "Initial version";
+    }
+
+    grouping l3vpn {
+        uses bgp-lu:labeled-unicast;
+        leaf route-distinguisher {
+            type bgp-t:route-distinguisher;
+        }
+    }
+
+    grouping l3vpn-ip-destination-type {
+        list vpn-destination {
+            uses l3vpn;
+        }
+    }
+
+    grouping l3vpn-ip-route {
+        list vpn-route {
+            key "route-key";
+            leaf route-key {
+                type binary;
+            }
+            uses l3vpn;
+            uses bgp-rib:route;
+        }
+    }
+}
\ No newline at end of file
diff --git a/bgp/l3vpn/src/main/yang/odl-bgp-vpn-ipv6-cfg.yang b/bgp/l3vpn/src/main/yang/odl-bgp-vpn-ipv6-cfg.yang
new file mode 100644 (file)
index 0000000..341090b
--- /dev/null
@@ -0,0 +1,40 @@
+module odl-bgp-vpn-ipv6-cfg {
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:bgp:vpn:ipv6";
+    prefix "bgp-vpn-cfg";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import odl-bgp-parser-spi-cfg { prefix bgpspi; revision-date 2013-11-15; }
+    import odl-bgp-rib-spi-cfg { prefix ribspi; revision-date 2013-11-15; }
+
+    organization "Brocade Communications Systems, Inc.";
+    contact "Kevin Wang <kwang@brocade.com>";
+
+    description
+        "This module contains the base YANG definitions for
+         BGP-MPLS IPv6 VPN extension.
+
+        Copyright (c) 2016 Brocade Communications Systems, Inc. All rights reserved.;
+
+        This program and the accompanying materials are made available
+        under the terms of the Eclipse Public License v1.0 which
+        accompanies this distribution, and is available at
+        http://www.eclipse.org/legal/epl-v10.html";
+
+    revision "2016-03-31" {
+        description
+            "Initial revision";
+    }
+
+    identity bgp-vpn-ipv6 {
+        base config:module-type;
+        config:provided-service bgpspi:extension;
+        config:provided-service ribspi:extension;
+        config:java-name-prefix VpnIpv6;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case bgp-vpn-ipv6 {
+            when "/config:modules/config:module/config:type = 'bgp-vpn-ipv6'";
+        }
+    }
+}
\ No newline at end of file
similarity index 87%
rename from bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/BGPActivatorTest.java
rename to bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/BgpIpv4ActivatorTest.java
index 59d4912e3a72841d559bbed9ab677c390d3a969c..602ab61f484758652afba35d79d27ada33c26dab 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.protocol.bgp.l3vpn;
+package org.opendaylight.protocol.bgp.l3vpn.ipv4;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -13,11 +13,11 @@ import org.junit.Test;
 import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
 import org.opendaylight.protocol.bgp.parser.spi.pojo.SimpleBGPExtensionProviderContext;
 
-public class BGPActivatorTest {
+public class BgpIpv4ActivatorTest {
 
     @Test
     public void testActivator() throws Exception {
-        final BGPActivator act = new BGPActivator();
+        final BgpIpv4Activator act = new BgpIpv4Activator();
         final BGPExtensionProviderContext context = new SimpleBGPExtensionProviderContext();
         assertFalse(context.getNlriRegistry().getSerializers().iterator().hasNext());
         act.start(context);
similarity index 97%
rename from bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/VpnIpv4NextHopTest.java
rename to bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4NextHopTest.java
index 4a49c19fb8d626b85fca48f54af43674e2517529..2657e42aeee9f6e54e2620e942abc2a65874695f 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.protocol.bgp.l3vpn;
+package org.opendaylight.protocol.bgp.l3vpn.ipv4;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
similarity index 73%
rename from bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/VpnIpv4NlriParserTest.java
rename to bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4NlriParserTest.java
index 85009b2584cdf815cfb5633bbca3e3c6a7107f0b..9623d68dcbd473c69d9acbc3bb1b320b1e442587 100644 (file)
@@ -5,7 +5,7 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-package org.opendaylight.protocol.bgp.l3vpn;
+package org.opendaylight.protocol.bgp.l3vpn.ipv4;
 
 import com.google.common.collect.Lists;
 import io.netty.buffer.ByteBuf;
@@ -33,18 +33,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisher;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisherBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv4CaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.vpn.ipv4._case.DestinationVpnIpv4Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.vpn.ipv4.destination.VpnIpv4Destination;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.vpn.ipv4.destination.VpnIpv4DestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.l3vpn.ipv4.destination.VpnIpv4DestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestinationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.MplsLabel;
 
-
 public class VpnIpv4NlriParserTest {
 
     private static final VpnIpv4NlriParser PARSER = new VpnIpv4NlriParser();
 
-    private static final byte[] NLRI_TYPE1 = new byte[] {
+    private static final byte[] NLRI_TYPE1 = new byte[]{
         (byte) 0x70,
         (byte) 0x00, (byte) 0x16, (byte) 0x31,
         0, 1, 1, 2, 3, 4, 1, 2,
@@ -54,15 +52,19 @@ public class VpnIpv4NlriParserTest {
     private static final List<LabelStack> LABEL_STACK = Lists.newArrayList(
         new LabelStackBuilder().setLabelValue(new MplsLabel(355L)).build());
     private static final RouteDistinguisher DISTINGUISHER = RouteDistinguisherBuilder.getDefaultInstance("1.2.3.4:258");
-    private static final VpnIpv4Destination VPN = new VpnIpv4DestinationBuilder().setRouteDistinguisher(DISTINGUISHER).setPrefix(IPv4_PREFIX).setLabelStack(LABEL_STACK).build();
+    private static final VpnDestination VPN = new VpnDestinationBuilder().setRouteDistinguisher(DISTINGUISHER).setPrefix(IPv4_PREFIX).setLabelStack(LABEL_STACK).build();
 
     @Test
     public void testMpReachNlri() throws BGPParsingException {
         final MpReachNlriBuilder mpBuilder = new MpReachNlriBuilder();
         mpBuilder.setAfi(Ipv4AddressFamily.class);
-        mpBuilder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
-            new DestinationVpnIpv4CaseBuilder().setDestinationVpnIpv4(
-                new DestinationVpnIpv4Builder().setVpnIpv4Destination(Lists.newArrayList(VPN)).build()).build()).build());
+        mpBuilder.setAdvertizedRoutes(
+            new AdvertizedRoutesBuilder().setDestinationType(
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv4CaseBuilder().setVpnIpv4Destination(
+                    new VpnIpv4DestinationBuilder().setVpnDestination(Lists.newArrayList(VPN)).build()
+                ).build()
+            ).build()
+        ).build();
 
         final MpReachNlri mpReachExpected = mpBuilder.build();
 
@@ -72,8 +74,11 @@ public class VpnIpv4NlriParserTest {
         Assert.assertEquals(mpReachExpected, testBuilder.build());
 
         final ByteBuf output = Unpooled.buffer();
-        PARSER.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes1.class,
-            new Attributes1Builder().setMpReachNlri(mpReachExpected).build()).build(), output);
+        PARSER.serializeAttribute(
+            new AttributesBuilder().addAugmentation(Attributes1.class,
+                new Attributes1Builder().setMpReachNlri(mpReachExpected).build()
+            ).build(), output
+        );
         Assert.assertArrayEquals(NLRI_TYPE1, ByteArray.readAllBytes(output));
     }
 
@@ -81,9 +86,13 @@ public class VpnIpv4NlriParserTest {
     public void testMpUnreachNlri() throws BGPParsingException {
         final MpUnreachNlriBuilder mpBuilder = new MpUnreachNlriBuilder();
         mpBuilder.setAfi(Ipv4AddressFamily.class);
-        mpBuilder.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
-            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv4CaseBuilder().setDestinationVpnIpv4(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.vpn.ipv4._case.DestinationVpnIpv4Builder().setVpnIpv4Destination(Lists.newArrayList(VPN)).build()).build()).build());
+        mpBuilder.setWithdrawnRoutes(
+            new WithdrawnRoutesBuilder().setDestinationType(
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv4CaseBuilder().setVpnIpv4Destination(
+                    new VpnIpv4DestinationBuilder().setVpnDestination(Lists.newArrayList(VPN)).build()
+                ).build()
+            ).build()
+        ).build();
 
         final MpUnreachNlri mpUnreachExpected = mpBuilder.build();
 
@@ -93,8 +102,11 @@ public class VpnIpv4NlriParserTest {
         Assert.assertEquals(mpUnreachExpected, testBuilder.build());
 
         final ByteBuf output = Unpooled.buffer();
-        PARSER.serializeAttribute(new AttributesBuilder().addAugmentation(Attributes2.class,
-            new Attributes2Builder().setMpUnreachNlri(mpUnreachExpected).build()).build(), output);
+        PARSER.serializeAttribute(
+            new AttributesBuilder().addAugmentation(Attributes2.class,
+                new Attributes2Builder().setMpUnreachNlri(mpUnreachExpected).build()
+            ).build(), output
+        );
         Assert.assertArrayEquals(NLRI_TYPE1, ByteArray.readAllBytes(output));
     }
 }
diff --git a/bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/BgpIpv6ActivatorTest.java b/bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/BgpIpv6ActivatorTest.java
new file mode 100644 (file)
index 0000000..8964857
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.l3vpn.ipv6;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
+import org.opendaylight.protocol.bgp.parser.spi.pojo.SimpleBGPExtensionProviderContext;
+
+/**
+ * @author Kevin Wang
+ */
+public class BgpIpv6ActivatorTest {
+
+    @Test
+    public void testActivator() throws Exception {
+        final BgpIpv6Activator act = new BgpIpv6Activator();
+        final BGPExtensionProviderContext context = new SimpleBGPExtensionProviderContext();
+        assertFalse(context.getNlriRegistry().getSerializers().iterator().hasNext());
+        act.start(context);
+        assertTrue(context.getNlriRegistry().getSerializers().iterator().next() instanceof VpnIpv6NlriParser);
+        act.close();
+    }
+}
\ No newline at end of file
diff --git a/bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6NextHopTest.java b/bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6NextHopTest.java
new file mode 100644 (file)
index 0000000..fa4620c
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.l3vpn.ipv6;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.net.Inet6Address;
+import org.junit.Test;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.protocol.util.Ipv6Util;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv6NextHopCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv6.next.hop._case.Ipv6NextHopBuilder;
+
+/**
+ * @author Kevin Wang
+ */
+public class VpnIpv6NextHopTest {
+
+    private static final VpnIpv6NextHopParserSerializer HANDLER = new VpnIpv6NextHopParserSerializer();
+
+    @Test
+    public void testSerializeIpv6NextHopCase() throws Exception {
+        final String TEST_IPV6_ADDRESS = "2001::1234:5678:90ab:cdef";   // put some random valid IPv6 address here
+
+        final ByteBuf buffer = Unpooled.buffer();
+        final byte[] nextHop = new byte[Ipv6Util.IPV6_LENGTH + RouteDistinguisherUtil.RD_LENGTH];
+        // now copy the IPv6 address to the byte array
+        System.arraycopy(Inet6Address.getByName(TEST_IPV6_ADDRESS).getAddress(), 0, nextHop, RouteDistinguisherUtil.RD_LENGTH, Ipv6Util.IPV6_LENGTH);
+        final CNextHop hop = new Ipv6NextHopCaseBuilder().setIpv6NextHop(new Ipv6NextHopBuilder()
+                .setGlobal(new Ipv6Address(TEST_IPV6_ADDRESS)).build()).build();
+
+        HANDLER.serializeNextHop(hop, buffer);
+        assertArrayEquals(nextHop, ByteArray.readAllBytes(buffer));
+
+        final CNextHop parsedHop = HANDLER.parseNextHop(Unpooled.wrappedBuffer(nextHop));
+        assertTrue(hop instanceof Ipv6NextHopCase);
+        assertEquals(hop, parsedHop);
+    }
+}
diff --git a/bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6NlriParserTest.java b/bgp/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6NlriParserTest.java
new file mode 100644 (file)
index 0000000..90e1c1e
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2016 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.bgp.l3vpn.ipv6;
+
+import com.google.common.collect.Lists;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.List;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.labeled.unicast.LabelStack;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.labeled.unicast.LabelStackBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisher;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisherBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.l3vpn.ipv6.destination.VpnIpv6DestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.MplsLabel;
+
+/**
+ * @author Kevin Wang
+ */
+public class VpnIpv6NlriParserTest {
+
+    private static final VpnIpv6NlriParser PARSER = new VpnIpv6NlriParser();
+
+    private static final byte[] NLRI_TYPE1 = new byte[]{
+        (byte) 0x88,    // length
+        (byte) 0x00, (byte) 0x16, (byte) 0x31,  // label
+        0, 1, 1, 2, 3, 4, 1, 2, // route distinguisher
+        (byte) 0x20, (byte) 0x01, (byte) 0x23, (byte) 0x45, (byte) 0x56, (byte) 0x89    // specify the IPv6 prefix here
+    };
+    private static final IpPrefix IPv6_PREFIX = new IpPrefix(new Ipv6Prefix("2001:2345:5689::/48"));
+    private static final List<LabelStack> LABEL_STACK = Lists.newArrayList(
+        new LabelStackBuilder().setLabelValue(new MplsLabel(355L)).build());
+    private static final RouteDistinguisher DISTINGUISHER = RouteDistinguisherBuilder.getDefaultInstance("1.2.3.4:258");
+    private static final VpnDestination VPN = new VpnDestinationBuilder().setRouteDistinguisher(DISTINGUISHER).setPrefix(IPv6_PREFIX).setLabelStack(LABEL_STACK).build();
+
+    @Test
+    public void testMpReachNlri() throws BGPParsingException {
+        final MpReachNlriBuilder mpBuilder = new MpReachNlriBuilder();
+        mpBuilder.setAfi(Ipv6AddressFamily.class);
+        mpBuilder.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv6CaseBuilder().setVpnIpv6Destination(
+                new VpnIpv6DestinationBuilder().setVpnDestination(Lists.newArrayList(VPN)).build()
+            ).build()
+            ).build()
+        ).build();
+
+        final MpReachNlri mpReachExpected = mpBuilder.build();
+
+        final MpReachNlriBuilder testBuilder = new MpReachNlriBuilder();
+        testBuilder.setAfi(Ipv6AddressFamily.class);
+        PARSER.parseNlri(Unpooled.copiedBuffer(NLRI_TYPE1), testBuilder);
+        Assert.assertEquals(mpReachExpected, testBuilder.build());
+
+        final ByteBuf output = Unpooled.buffer();
+        PARSER.serializeAttribute(
+            new AttributesBuilder().addAugmentation(Attributes1.class,
+                new Attributes1Builder().setMpReachNlri(mpReachExpected).build()
+            ).build(), output
+        );
+        Assert.assertArrayEquals(NLRI_TYPE1, ByteArray.readAllBytes(output));
+    }
+
+    @Test
+    public void testMpUnreachNlri() throws BGPParsingException {
+        final MpUnreachNlriBuilder mpBuilder = new MpUnreachNlriBuilder();
+        mpBuilder.setAfi(Ipv6AddressFamily.class);
+        mpBuilder.setWithdrawnRoutes(
+            new WithdrawnRoutesBuilder().setDestinationType(
+                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv6CaseBuilder().setVpnIpv6Destination(
+                    new VpnIpv6DestinationBuilder().setVpnDestination(Lists.newArrayList(VPN)).build()
+                ).build()
+            ).build()
+        ).build();
+
+        final MpUnreachNlri mpUnreachExpected = mpBuilder.build();
+
+        final MpUnreachNlriBuilder testBuilder = new MpUnreachNlriBuilder();
+        testBuilder.setAfi(Ipv6AddressFamily.class);
+        PARSER.parseNlri(Unpooled.copiedBuffer(NLRI_TYPE1), testBuilder);
+        Assert.assertEquals(mpUnreachExpected, testBuilder.build());
+
+        final ByteBuf output = Unpooled.buffer();
+        PARSER.serializeAttribute(
+            new AttributesBuilder().addAugmentation(Attributes2.class,
+                new Attributes2Builder().setMpUnreachNlri(mpUnreachExpected).build()
+            ).build(), output
+        );
+        Assert.assertArrayEquals(NLRI_TYPE1, ByteArray.readAllBytes(output));
+    }
+}
index 1c6374ce5bfac9599b2ea5439aa38c1db9e173f6..7168dbb88232d0e5080b9384ede3a14602bb42fd 100644 (file)
@@ -80,7 +80,11 @@ public abstract class AbstractRIBSupport implements RIBSupport {
         this.cazeClass = Preconditions.checkNotNull(cazeClass);
         this.containerClass = Preconditions.checkNotNull(containerClass);
         this.listClass = Preconditions.checkNotNull(listClass);
-        this.routesListIdentifier = new NodeIdentifier(BindingReflections.findQName(listClass).intern());
+        this.routesListIdentifier = new NodeIdentifier(
+            QName.create(
+                qname.getNamespace(), qname.getRevision(), BindingReflections.findQName(listClass).intern().getLocalName()
+            )
+        );
     }
 
     @Override