BUG-4826: BGP Evpn Rib support 23/37923/3
authorClaudio D. Gasparini <cgaspari@cisco.com>
Tue, 5 Apr 2016 09:29:54 +0000 (11:29 +0200)
committerMilos Fabian <milfabia@cisco.com>
Wed, 20 Apr 2016 17:38:13 +0000 (17:38 +0000)
Implementation of Rib support, Activators, and registration
of handlers.

Change-Id: I7cfadabb7f267c326e58a4f80e323008638faa01
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
artifacts/pom.xml
bgp/controller-config/src/main/resources/initial/31-bgp.xml
bgp/controller-config/src/main/resources/initial/41-bgp-example.xml
bgp/evpn/pom.xml
bgp/evpn/src/main/java/org/opendaylight/controller/config/yang/bgp/evpn/EvpnModule.java
bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/EvpnRibSupport.java [new file with mode: 0644]
bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/RIBActivator.java [new file with mode: 0644]
features/bgp/pom.xml
features/bgp/src/main/features/features.xml

index f4099ba7927daa49854db875cee198b7fc281c92..9ef24a31e92cede60bc13c10d0c06500bd519dc0 100644 (file)
                 <artifactId>bgp-linkstate</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>bgp-evpn</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>bgp-inet</artifactId>
index 4544a3af9bccc10642996bbbd7a7abea5cb19069..45d1df70630d56d97fc35e22df173899ed440bdf 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: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>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl?module=odl-bgp-rib-impl-cfg&amp;revision=2016-03-30</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-evpn</name>
+                    </extension>
                 </module>
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:base-bgp-parser</type>
                         <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-evpn</name>
+                    </extension>
                 </module>
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:base-bgp-rib</type>
                     <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:evpn">prefix:bgp-evpn</type>
+                    <name>bgp-evpn</name>
+                </module>
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-dispatcher-impl</type>
                     <name>global-bgp-dispatcher</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>evpn</name>
+                    <afi xmlns:bgp="urn:opendaylight:params:xml:ns:yang:bgp-evpn">bgp:l2vpn-address-family</afi>
+                    <safi xmlns:bgp-types="urn:opendaylight:params:xml:ns:yang:bgp-evpn">bgp-types:evpn-subsequent-address-family</safi>
+                </module>
             </modules>
 
             <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
                         <name>bgp-vpn-ipv4</name>
                         <provider>/modules/module[type='bgp-vpn-ipv4'][name='bgp-vpn-ipv4']</provider>
                     </instance>
+                    <instance>
+                        <name>bgp-evpn</name>
+                        <provider>/modules/module[type='bgp-evpn'][name='bgp-evpn']</provider>
+                    </instance>
                 </service>
                 <service>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-table-type</type>
                         <name>ipv4-l3vpn</name>
                         <provider>/modules/module[type='bgp-table-type-impl'][name='ipv4-l3vpn']</provider>
                     </instance>
+                    <instance>
+                        <name>evpn</name>
+                        <provider>/modules/module[type='bgp-table-type-impl'][name='evpn']</provider>
+                    </instance>
                 </service>
                 <service>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:add-path</type>
                         <name>bgp-vpn-ipv4</name>
                         <provider>/modules/module[type='bgp-vpn-ipv4'][name='bgp-vpn-ipv4']</provider>
                     </instance>
+                    <instance>
+                        <name>bgp-evpn</name>
+                        <provider>/modules/module[type='bgp-evpn'][name='bgp-evpn']</provider>
+                    </instance>
                 </service>
                 <service>
                     <type xmlns:ribspi="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:spi">ribspi:extensions</type>
index 585b4a000ab864161d8e30f3f8efb6840b3446fc..10edd367c8432b1414b7a4114ae851d8f3248982 100755 (executable)
                         <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>evpn</name>
+                    </advertized-table>
                     <add-path>
                         <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:add-path</type>
                         <name>ipv4-unicast-both</name>
                         <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>evpn</name>
+                    </local-table>
                     <!--<rib-path-selection-mode>
                         <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl">prefix:bgp-path-selection-mode</type>
                         <name>ipv4-unicast-path-selection-mode</name>
index d527a0f2de93274186a5bccadddf71af5b1fc440..46a8bba66e51971a99f18b2cf0fc95cc136e563d 100644 (file)
 <project xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</developerConnection>
+        <url>https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main</url>
+        <tag>HEAD</tag>
+    </scm>
     <parent>
         <artifactId>bgp-parent</artifactId>
         <groupId>org.opendaylight.bgpcep</groupId>
         <version>0.6.0-SNAPSHOT</version>
     </parent>
-    <modelVersion>4.0.0</modelVersion>
 
     <artifactId>bgp-evpn</artifactId>
+    <description>BGP Evpn</description>
+    <packaging>bundle</packaging>
+    <name>${project.artifactId}</name>
+    <prerequisites>
+        <maven>3.0.4</maven>
+    </prerequisites>
 
     <dependencies>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>bgp-bmp-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
         <!-- test scope dependencies -->
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-manager</artifactId>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-manager</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>bgp-rib-spi</artifactId>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>bgp-parser-spi</artifactId>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>mockito-configuration</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
     <build>
         <plugins>
index 80c5c97aadc3b705dc1dc56da4bc0cd1803b669b..0412cb6cffb7206c896a11326a69f8726e8022ba 100644 (file)
@@ -6,6 +6,14 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 package org.opendaylight.controller.config.yang.bgp.evpn;
+
+import org.opendaylight.protocol.bgp.evpn.impl.BGPActivator;
+import org.opendaylight.protocol.bgp.evpn.impl.RIBActivator;
+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 EvpnModule extends org.opendaylight.controller.config.yang.bgp.evpn.AbstractEvpnModule {
     public EvpnModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
@@ -22,8 +30,41 @@ public class EvpnModule extends org.opendaylight.controller.config.yang.bgp.evpn
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        // TODO:implement
-        throw new java.lang.UnsupportedOperationException();
+        final class EvpnExtension implements AutoCloseable, BGPExtensionProviderActivator, RIBExtensionProviderActivator {
+            private final BGPExtensionProviderActivator bgpActivator = new BGPActivator();
+            private final RIBExtensionProviderActivator ribActivator = new RIBActivator();
+
+            @Override
+            public void close() throws Exception {
+                if (this.bgpActivator != null) {
+                    this.bgpActivator.stop();
+                }
+                if (this.ribActivator != null) {
+                    this.ribActivator.stopRIBExtensionProvider();
+                }
+            }
+
+            @Override
+            public void start(final BGPExtensionProviderContext context) {
+                this.bgpActivator.start(context);
+            }
+
+            @Override
+            public void stop() {
+                this.bgpActivator.stop();
+            }
+
+            @Override
+            public void startRIBExtensionProvider(final RIBExtensionProviderContext context) {
+                this.ribActivator.startRIBExtensionProvider(context);
+            }
+
+            @Override
+            public void stopRIBExtensionProvider() {
+                this.ribActivator.stopRIBExtensionProvider();
+            }
+        }
+        return new EvpnExtension();
     }
 
 }
diff --git a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/EvpnRibSupport.java b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/EvpnRibSupport.java
new file mode 100644 (file)
index 0000000..8c2e845
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * 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.evpn.impl;
+
+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.evpn.impl.nlri.EvpnNlriParser;
+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.evpn.rev160321.EvpnSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.L2vpnAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.application.rib.tables.routes.EvpnRoutesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.destination.EvpnDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.routes.EvpnRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.routes.evpn.routes.EvpnRoute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.evpn._case.DestinationEvpn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationEvpnCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.evpn._case.DestinationEvpnBuilder;
+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.rib.rev130925.rib.tables.Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+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 EvpnRibSupport extends AbstractRIBSupport {
+    private static final EvpnRibSupport SINGLETON = new EvpnRibSupport();
+    private static final Logger LOG = LoggerFactory.getLogger(EvpnRibSupport.class);
+    private static final QName ROUTE_KEY = QName.create(EvpnRoute.QNAME, "route-key").intern();
+    private static final NodeIdentifier DESTINATION = NodeIdentifier.create(DestinationEvpn.QNAME);
+    private static final NodeIdentifier NLRI_ROUTES_LIST = NodeIdentifier.create(EvpnDestination.QNAME);
+    private static final NodeIdentifier ROUTE = NodeIdentifier.create(EvpnRoute.QNAME);
+
+    private static final ApplyRoute DELETE_ROUTE = new DeleteRoute();
+    private static final ApplyRoute PUT_ROUTE = new PutRoute();
+    private static final ChoiceNode EMPTY_ROUTES = Builders.choiceBuilder().withNodeIdentifier(NodeIdentifier.create(Routes.QNAME))
+        .addChild(Builders.containerBuilder().withNodeIdentifier(NodeIdentifier.create(EvpnRoutes.QNAME))
+            .addChild(ImmutableNodes.mapNodeBuilder(EvpnRoute.QNAME).build()).build()).build();
+
+    private EvpnRibSupport() {
+        super(EvpnRoutesCase.class, EvpnRoutes.class, EvpnRoute.class);
+    }
+
+    private interface ApplyRoute {
+        void apply(DOMDataWriteTransaction tx, YangInstanceIdentifier base, NodeIdentifierWithPredicates routeKey, DataContainerNode<?> route,
+            ContainerNode attributes, NodeIdentifier nodeIdentifier);
+    }
+
+    private static class DeleteRoute implements ApplyRoute {
+        @Override
+        public void apply(final DOMDataWriteTransaction tx, final YangInstanceIdentifier base, final NodeIdentifierWithPredicates routeKey,
+            final DataContainerNode<?> route, final ContainerNode attributes, final NodeIdentifier nodeIdentifier) {
+            tx.delete(LogicalDatastoreType.OPERATIONAL, base.node(routeKey));
+        }
+    }
+
+    private static final class PutRoute implements ApplyRoute {
+        private ContainerNode addAttributes(final ContainerNode attributes, final NodeIdentifier routeAttII) {
+            final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> cb = Builders.containerBuilder(attributes);
+            cb.withNodeIdentifier(routeAttII);
+            return cb.build();
+        }
+
+        @Override
+        public void apply(final DOMDataWriteTransaction tx, final YangInstanceIdentifier base, final NodeIdentifierWithPredicates routeKey,
+            final DataContainerNode<?> route, final ContainerNode attributes, final NodeIdentifier routeAttII) {
+            final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> b = ImmutableNodes.mapEntryBuilder();
+            b.withNodeIdentifier(routeKey);
+
+            route.getValue().forEach(b::withChild);
+            b.withChild(addAttributes(attributes, routeAttII));
+            tx.put(LogicalDatastoreType.OPERATIONAL, base.node(routeKey), b.build());
+        }
+    }
+
+    static EvpnRibSupport getInstance() {
+        return SINGLETON;
+    }
+
+    @Nonnull
+    @Override
+    public ChoiceNode emptyRoutes() {
+        return EMPTY_ROUTES;
+    }
+
+    @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;
+    }
+
+    @Nonnull
+    @Override
+    protected NodeIdentifier destinationContainerIdentifier() {
+        return DESTINATION;
+    }
+
+    @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, PUT_ROUTE);
+    }
+
+    @Nonnull
+    @Override
+    protected MpReachNlri buildReach(final Collection<MapEntryNode> routes, final CNextHop hop) {
+        final MpReachNlriBuilder mb = new MpReachNlriBuilder();
+        mb.setAfi(L2vpnAddressFamily.class);
+        mb.setSafi(EvpnSubsequentAddressFamily.class);
+        mb.setCNextHop(hop);
+
+        final List<EvpnDestination> dests = new ArrayList<>(routes.size());
+        dests.addAll(routes.stream().map(EvpnNlriParser::extractEvpnDestination).collect(Collectors.toList()));
+        mb.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationEvpnCaseBuilder()
+            .setDestinationEvpn(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update
+                .attributes.mp.reach.nlri.advertized.routes.destination.type.destination.evpn._case.DestinationEvpnBuilder().setEvpnDestination(dests).build()).build()).build());
+        return mb.build();
+    }
+
+    @Nonnull
+    @Override
+    protected MpUnreachNlri buildUnreach(final Collection<MapEntryNode> routes) {
+        final MpUnreachNlriBuilder mb = new MpUnreachNlriBuilder();
+        mb.setAfi(L2vpnAddressFamily.class);
+        mb.setSafi(EvpnSubsequentAddressFamily.class);
+
+        final List<EvpnDestination> dests = new ArrayList<>(routes.size());
+        dests.addAll(routes.stream().map(EvpnNlriParser::extractEvpnDestination).collect(Collectors.toList()));
+        mb.setWithdrawnRoutes(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp
+            .unreach.nlri.WithdrawnRoutesBuilder().setDestinationType(new DestinationEvpnCaseBuilder().setDestinationEvpn(
+            new DestinationEvpnBuilder().setEvpnDestination(dests).build()).build()).build()).build();
+        return mb.build();
+    }
+
+    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, routeAttributesIdentifier());
+                    }
+                } else {
+                    LOG.warn("Routes {} are not a map", routes);
+                }
+            }
+        }
+    }
+
+    private NodeIdentifierWithPredicates createRouteKey(final UnkeyedListEntryNode evpn) {
+        final ByteBuf buffer = Unpooled.buffer();
+        final EvpnDestination dest = EvpnNlriParser.extractRouteKeyDestination(evpn);
+        EvpnNlriParser.serializeNlri(Collections.singletonList(dest), buffer);
+        return new NodeIdentifierWithPredicates(EvpnRoute.QNAME, ROUTE_KEY, ByteArray.readAllBytes(buffer));
+    }
+
+}
diff --git a/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/RIBActivator.java b/bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/RIBActivator.java
new file mode 100644 (file)
index 0000000..e482d25
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.evpn.impl;
+
+import java.util.Collections;
+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.evpn.rev160321.EvpnSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.L2vpnAddressFamily;
+
+public final class RIBActivator extends AbstractRIBExtensionProviderActivator {
+
+    @Override
+    protected List<AutoCloseable> startRIBExtensionProviderImpl(final RIBExtensionProviderContext context) {
+        return Collections.singletonList(context.registerRIBSupport(L2vpnAddressFamily.class, EvpnSubsequentAddressFamily.class,
+            EvpnRibSupport.getInstance()));
+    }
+}
\ No newline at end of file
index 970e85f3e712cdb0b6a42c940c760ad050543f90..593fd96df3af8c99a663d10392963446c0f71b35 100644 (file)
           <groupId>${project.groupId}</groupId>
           <artifactId>bgp-l3vpn</artifactId>
       </dependency>
+      <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>bgp-evpn</artifactId>
+      </dependency>
       <dependency>
           <groupId>${project.groupId}</groupId>
           <artifactId>bgp-inet</artifactId>
index 26da346fe55faec5d0342060e73c66ca1338857e..fd17bbbd3837049f878089ff51f5d91c662c0402 100644 (file)
@@ -34,6 +34,7 @@
         <feature version='${project.version}'>odl-bgpcep-bgp-flowspec</feature>
         <feature version='${project.version}'>odl-bgpcep-bgp-labeled-unicast</feature>
         <feature version='${project.version}'>odl-bgpcep-bgp-l3vpn</feature>
+        <feature version='${project.version}'>odl-bgpcep-bgp-evpn</feature>
         <feature version='${project.version}'>odl-bgpcep-bgp-path-selection-mode</feature>
         <feature version='${project.version}'>odl-bgpcep-bgp-topology</feature>
         <feature version='${project.version}'>odl-bgpcep-bgp-openconfig</feature>
         <bundle>mvn:org.opendaylight.bgpcep/bgp-bmp-api/{{VERSION}}</bundle>
     </feature>
 
+    <feature name='odl-bgpcep-bgp-evpn' version='${project.version}'>
+        <feature version='${project.version}'>odl-bgpcep-bgp-parser</feature>
+        <feature version='${project.version}'>odl-bgpcep-bgp-rib-api</feature>
+        <bundle>mvn:org.opendaylight.bgpcep/bgp-evpn/{{VERSION}}</bundle>
+        <bundle>mvn:org.opendaylight.bgpcep/bgp-bmp-api/{{VERSION}}</bundle>
+    </feature>
+
     <feature name='odl-bgpcep-bgp-path-selection-mode' version='${project.version}'>
         <feature version='${project.version}'>odl-bgpcep-bgp-dependencies</feature>
         <feature version='${config.version}'>odl-config-api</feature>