Rib Out Route Paths re evaluation. 34/73534/2
authorClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Mon, 25 Jun 2018 12:17:10 +0000 (14:17 +0200)
committerClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Thu, 28 Jun 2018 13:58:44 +0000 (15:58 +0200)
Allow to perfom a reevaluation of one specific table,
and update rib out for an specific peer.
This will allow to re evaluate paths advertized
for an specific peer when two families are interconnected
like RT and VPN, reducing the volume of message it can
produce to reevaluate the full table for all peers.

JIRA: BGPCEP-527
Change-Id: I3056aa2e4a2e9b94fb9c4a1c99a09fe972500f4f
Signed-off-by: Claudio D. Gasparini <claudio.gasparini@pantheon.tech>
12 files changed:
bgp/rib-impl/pom.xml
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AbstractPeer.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeer.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/EffectiveRibInWriter.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/LocRibWriter.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RouteTargetMembeshipUtil.java [new file with mode: 0644]
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/RibImpl.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RIB.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RibOutRefresh.java [new file with mode: 0644]
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/Peer.java

index 17575c6e63d66cfca90fd1e3b6cdfbd15fba1edd..cd70e80bc1f64e856a1fef1a4adfa3e5f203d054 100644 (file)
             <groupId>${project.groupId}</groupId>
             <artifactId>bgp-inet</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>bgp-route-target</artifactId>
+        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>bgp-parser-api</artifactId>
index 3085fb21943f4ca88609ac0313ce99cdecc2b831..454169c89fc9eb931ac2d5c1fc9f0333d5d9fa21 100644 (file)
@@ -295,6 +295,64 @@ abstract class AbstractPeer extends BGPPeerStateImpl implements BGPRouteEntryImp
         }, MoreExecutors.directExecutor());
     }
 
+    public final synchronized <C extends Routes & DataObject & ChoiceIn<Tables>, S extends ChildOf<? super C>,
+            R extends Route & ChildOf<? super S> & Identifiable<I>,
+            I extends Identifier<R>> void reEvaluateAdvertizement(
+            final RouteEntryDependenciesContainer entryDep,
+            List<ActualBestPathRoutes<C, S, R, I>> routesToStore) {
+        if (this.bindingChain == null) {
+            LOG.debug("Session closed, skip changes to peer AdjRibsOut {}", getPeerId());
+            return;
+        }
+
+        final RIBSupport<C,S,R,I> ribSupport = entryDep.getRIBSupport();
+        final TablesKey tk = entryDep.getRIBSupport().getTablesKey();
+        final boolean addPathSupported = supportsAddPathSupported(tk);
+
+        final WriteTransaction tx = this.bindingChain.newWriteOnlyTransaction();
+        for(final ActualBestPathRoutes<C,S,R,I> actualBestRoute :routesToStore) {
+            final PeerId fromPeerId = actualBestRoute.getFromPeerId();
+            final Peer fromPeer = entryDep.getPeerTracker().getPeer(fromPeerId);
+            if (!filterRoutes(fromPeerId, ribSupport.getTablesKey())) {
+                continue;
+            }
+            final R route = actualBestRoute.getRoute();
+
+            final BGPRouteEntryExportParameters routeEntry = new BGPRouteEntryExportParametersImpl(fromPeer, this);
+            final Optional<Attributes> effAttr = entryDep.getRoutingPolicies()
+                    .applyExportPolicies(routeEntry, actualBestRoute.getAttributes(), entryDep.getAfiSafType());
+            final KeyedInstanceIdentifier<Tables, TablesKey> tableRibout = getRibOutIId(tk);
+            if (effAttr.isPresent()) {
+                storeRoute(ribSupport, addPathSupported, tableRibout, actualBestRoute, route, effAttr.get(), tx);
+            } else {
+                final InstanceIdentifier<R> ribOut;
+                if (!addPathSupported) {
+                    ribOut = ribSupport.createRouteIdentifier(tableRibout,
+                            actualBestRoute.getNonAddPathRouteKeyIdentifier());
+                } else {
+                    ribOut = ribSupport.createRouteIdentifier(tableRibout,
+                            actualBestRoute.getAddPathRouteKeyIdentifier());
+                }
+                LOG.debug("Write advRoute {} to peer AdjRibsOut {}", actualBestRoute, getPeerId());
+                tx.delete(LogicalDatastoreType.OPERATIONAL, ribOut);
+            }
+        }
+
+        final FluentFuture<? extends CommitInfo> future = tx.commit();
+        this.submitted = future;
+        future.addCallback(new FutureCallback<CommitInfo>() {
+            @Override
+            public void onSuccess(final CommitInfo result) {
+                LOG.trace("Successful update commit");
+            }
+
+            @Override
+            public void onFailure(final Throwable trw) {
+                LOG.error("Failed update commit", trw);
+            }
+        }, MoreExecutors.directExecutor());
+    }
+
     private <C extends Routes & DataObject & ChoiceIn<Tables>, S extends ChildOf<? super C>,
             R extends Route & ChildOf<? super S> & Identifiable<I>, I extends Identifier<R>>
     void installRouteRibOut(final RouteEntryDependenciesContainer entryDep,
index 6d91e7415e33e5d90a798e508edfb646815f0236..0a29193ecac8ab897721943371e921adfa6ec3a7 100644 (file)
@@ -153,8 +153,8 @@ public class ApplicationPeer extends AbstractPeer implements ClusteredDOMDataTre
         this.adjRibInWriter = this.adjRibInWriter.transform(this.peerId, this.peerPath, context, localTables,
                 Collections.emptyMap(), registerAppPeerListener);
         this.effectiveRibInWriter = new EffectiveRibInWriter(this, this.rib,
-                this.rib.createPeerChain(this), this.peerIId, localTables, this.tableTypeRegistry
-        );
+                this.rib.createPeerChain(this), this.peerIId, localTables, this.tableTypeRegistry,
+                Collections.emptyList());
         this.effectiveRibInWriter.init();
         this.bgpSessionState.registerMessagesCounter(this);
         this.trackerRegistration = this.rib.getPeerTracker().registerPeer(this);
index ec1624c4b72c81492894b2ad6144cbf03c203f91..b412bcb79700f8d85dd1c57018f7a52e56a44a6a 100644 (file)
@@ -336,7 +336,7 @@ public class BGPPeer extends AbstractPeer implements BGPSessionListener {
         this.tables = ImmutableSet.copyOf(setTables);
         this.effRibInWriter = new EffectiveRibInWriter(this, this.rib,
                 this.rib.createPeerChain(this),
-                peerIId, this.tables, this.tableTypeRegistry);
+                peerIId, this.tables, this.tableTypeRegistry, rtMemberships);
         registerPrefixesCounters(this.effRibInWriter, this.effRibInWriter);
         this.peerRibOutIId = peerIId.child(AdjRibOut.class);
         this.effRibInWriter.init();
index b5178712092f615a0f0e98a8df59a3f34f58bd5a..0acbb68bf97270faccb640a3121776c13142994e 100644 (file)
@@ -15,6 +15,7 @@ import com.google.common.util.concurrent.FluentFuture;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.MoreExecutors;
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
@@ -35,6 +36,7 @@ import org.opendaylight.mdsal.common.api.CommitInfo;
 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
+import org.opendaylight.protocol.bgp.rib.impl.spi.RibOutRefresh;
 import org.opendaylight.protocol.bgp.rib.impl.state.peer.PrefixesInstalledCounters;
 import org.opendaylight.protocol.bgp.rib.impl.state.peer.PrefixesReceivedCounters;
 import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
@@ -50,6 +52,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv6AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.MplsLabeledVpnSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteTarget;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.ChildOf;
 import org.opendaylight.yangtools.yang.binding.ChoiceIn;
@@ -79,11 +85,16 @@ final class EffectiveRibInWriter implements PrefixesReceivedCounters, PrefixesIn
 
     private static final Logger LOG = LoggerFactory.getLogger(EffectiveRibInWriter.class);
     static final NodeIdentifier TABLE_ROUTES = new NodeIdentifier(Routes.QNAME);
-
+    private static final TablesKey IVP4_VPN_TABLE_KEY = new TablesKey(Ipv4AddressFamily.class,
+            MplsLabeledVpnSubsequentAddressFamily.class);
+    private static final TablesKey IVP6_VPN_TABLE_KEY = new TablesKey(Ipv6AddressFamily.class,
+            MplsLabeledVpnSubsequentAddressFamily.class);
     private final RIBSupportContextRegistry registry;
     private final KeyedInstanceIdentifier<Peer, PeerKey> peerIId;
     private final InstanceIdentifier<EffectiveRibIn> effRibTables;
     private final DataBroker databroker;
+    private final List<RouteTarget> rtMemberships;
+    private final RibOutRefresh vpnTableRefresher;
     private ListenerRegistration<?> reg;
     private BindingTransactionChain chain;
     private final Map<TablesKey, LongAdder> prefixesReceived;
@@ -93,6 +104,7 @@ final class EffectiveRibInWriter implements PrefixesReceivedCounters, PrefixesIn
     private final BGPTableTypeRegistryConsumer tableTypeRegistry;
     @GuardedBy("this")
     private FluentFuture<? extends CommitInfo> submitted;
+    private boolean rtMembershipsUpdated;
 
     EffectiveRibInWriter(
             final BGPRouteEntryImportParameters peer,
@@ -100,8 +112,8 @@ final class EffectiveRibInWriter implements PrefixesReceivedCounters, PrefixesIn
             final BindingTransactionChain chain,
             final KeyedInstanceIdentifier<Peer, PeerKey> peerIId,
             final Set<TablesKey> tables,
-            final BGPTableTypeRegistryConsumer tableTypeRegistry
-    ) {
+            final BGPTableTypeRegistryConsumer tableTypeRegistry,
+            final List<RouteTarget> rtMemberships) {
         this.registry = requireNonNull(rib.getRibSupportContext());
         this.chain = requireNonNull(chain);
         this.peerIId = requireNonNull(peerIId);
@@ -112,6 +124,8 @@ final class EffectiveRibInWriter implements PrefixesReceivedCounters, PrefixesIn
         this.databroker = requireNonNull(rib.getDataBroker());
         this.tableTypeRegistry = requireNonNull(tableTypeRegistry);
         this.peerImportParameters = peer;
+        this.rtMemberships = rtMemberships;
+        this.vpnTableRefresher = rib;
     }
 
     public void init() {
@@ -201,6 +215,13 @@ final class EffectiveRibInWriter implements PrefixesReceivedCounters, PrefixesIn
                 }
             }, MoreExecutors.directExecutor());
         }
+
+        //Refresh VPN Table if RT Memberships were updated
+        if (this.rtMembershipsUpdated) {
+            this.vpnTableRefresher.refreshTable(IVP4_VPN_TABLE_KEY, this.peerImportParameters.getFromPeerId());
+            this.vpnTableRefresher.refreshTable(IVP6_VPN_TABLE_KEY, this.peerImportParameters.getFromPeerId());
+            this.rtMembershipsUpdated = false;
+        }
     }
 
     @SuppressWarnings("unchecked")
@@ -237,10 +258,20 @@ final class EffectiveRibInWriter implements PrefixesReceivedCounters, PrefixesIn
                 .applyImportPolicies(this.peerImportParameters, route.getAttributes(),
                         tableTypeRegistry.getAfiSafiType(ribSupport.getTablesKey()).get());
         if (effAtt.isPresent()) {
+            final Optional<RouteTarget> rtMembership = RouteTargetMembeshipUtil.getRT(route);
+            if (rtMembership.isPresent()) {
+                this.rtMemberships.add(rtMembership.get());
+                this.rtMembershipsUpdated = true;
+            }
             CountersUtil.increment(this.prefixesInstalled.get(tk), tk);
             tx.put(LogicalDatastoreType.OPERATIONAL, routeIID, route);
             tx.put(LogicalDatastoreType.OPERATIONAL, routeIID.child(Attributes.class), effAtt.get());
         } else {
+            final Optional<RouteTarget> rtMembership = RouteTargetMembeshipUtil.getRT(route);
+            if (rtMembership.isPresent()) {
+                this.rtMemberships.remove(rtMembership.get());
+                this.rtMembershipsUpdated = true;
+            }
             tx.delete(LogicalDatastoreType.OPERATIONAL, routeIID);
         }
     }
index 671af0a551884e4c6d0f8e350eba870179d1af8a..30f89b32f5953596feea192c27cc66b75d2f9d2e 100644 (file)
@@ -33,6 +33,7 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.mdsal.common.api.CommitInfo;
 import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
 import org.opendaylight.protocol.bgp.mode.api.RouteEntry;
+import org.opendaylight.protocol.bgp.rib.impl.spi.RibOutRefresh;
 import org.opendaylight.protocol.bgp.rib.impl.state.rib.TotalPathsCounter;
 import org.opendaylight.protocol.bgp.rib.impl.state.rib.TotalPrefixesCounter;
 import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
@@ -44,6 +45,7 @@ import org.opendaylight.protocol.bgp.rib.spi.entry.StaleBestPathRoute;
 import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.AfiSafiType;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.Route;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.Rib;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.RibKey;
@@ -70,7 +72,7 @@ import org.slf4j.LoggerFactory;
 @NotThreadSafe
 final class LocRibWriter<C extends Routes & DataObject & ChoiceIn<Tables>, S extends ChildOf<? super C>,
         R extends Route & ChildOf<? super S> & Identifiable<I>, I extends Identifier<R>>
-        implements AutoCloseable, TotalPrefixesCounter, TotalPathsCounter,
+        implements AutoCloseable, RibOutRefresh, TotalPrefixesCounter, TotalPathsCounter,
         ClusteredDataTreeChangeListener<Tables> {
 
     private static final Logger LOG = LoggerFactory.getLogger(LocRibWriter.class);
@@ -225,9 +227,9 @@ final class LocRibWriter<C extends Routes & DataObject & ChoiceIn<Tables>, S ext
     }
 
     @SuppressWarnings("unchecked")
-    private Map<RouteUpdateKey, RouteEntry<C,S,R,I>> update(final WriteTransaction tx,
+    private Map<RouteUpdateKey, RouteEntry<C, S, R, I>> update(final WriteTransaction tx,
             final Collection<DataTreeModification<Tables>> changes) {
-        final Map<RouteUpdateKey, RouteEntry<C,S,R,I>> ret = new HashMap<>();
+        final Map<RouteUpdateKey, RouteEntry<C, S, R, I>> ret = new HashMap<>();
         for (final DataTreeModification<Tables> tc : changes) {
             final DataObjectModification<Tables> table = tc.getRootNode();
             final DataTreeIdentifier<Tables> rootPath = tc.getRootPath();
@@ -242,9 +244,9 @@ final class LocRibWriter<C extends Routes & DataObject & ChoiceIn<Tables>, S ext
                         = this.peerTracker.getPeer(peerKIid.getKey().getPeerId());
                 if (toPeer != null && toPeer.supportsTable(this.entryDep.getLocalTablesKey())) {
                     LOG.debug("Peer {} table has been created, inserting existent routes", toPeer.getPeerId());
-                    final List<ActualBestPathRoutes<C,S,R,I>> routesToStore = new ArrayList<>();
-                    for (final Map.Entry<String, RouteEntry<C,S,R,I>> entry:this.routeEntries.entrySet()) {
-                        final List<ActualBestPathRoutes<C,S,R,I>> filteredRoute = entry.getValue()
+                    final List<ActualBestPathRoutes<C, S, R, I>> routesToStore = new ArrayList<>();
+                    for (final Map.Entry<String, RouteEntry<C, S, R, I>> entry : this.routeEntries.entrySet()) {
+                        final List<ActualBestPathRoutes<C, S, R, I>> filteredRoute = entry.getValue()
                                 .actualBestPaths(this.ribSupport, new RouteEntryInfoImpl(toPeer, entry.getKey()));
                         routesToStore.addAll(filteredRoute);
                     }
@@ -379,4 +381,19 @@ final class LocRibWriter<C extends Routes & DataObject & ChoiceIn<Tables>, S ext
     TablesKey getTableKey() {
         return this.tk;
     }
+
+    @Override
+    public synchronized void refreshTable(final TablesKey tk, final PeerId peerId) {
+        final org.opendaylight.protocol.bgp.rib.spi.Peer toPeer = this.peerTracker.getPeer(peerId);
+        if (toPeer != null && toPeer.supportsTable(this.entryDep.getLocalTablesKey())) {
+            LOG.debug("Peer {} table has been created, inserting existent routes", toPeer.getPeerId());
+            final List<ActualBestPathRoutes<C, S, R, I>> routesToStore = new ArrayList<>();
+            for (final Map.Entry<String, RouteEntry<C, S, R, I>> entry : this.routeEntries.entrySet()) {
+                final List<ActualBestPathRoutes<C, S, R, I>> filteredRoute = entry.getValue()
+                        .actualBestPaths(this.ribSupport, new RouteEntryInfoImpl(toPeer, entry.getKey()));
+                routesToStore.addAll(filteredRoute);
+            }
+            toPeer.reEvaluateAdvertizement(this.entryDep, routesToStore);
+        }
+    }
 }
index 3fd2a7731fcbdacd6a6a686e30412daffd72db67..2c967744ab7a021b304ee35f9af0adaac46e24e9 100755 (executable)
@@ -43,6 +43,7 @@ import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
 import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
+import org.opendaylight.protocol.bgp.rib.impl.spi.RibOutRefresh;
 import org.opendaylight.protocol.bgp.rib.impl.state.BGPRIBStateImpl;
 import org.opendaylight.protocol.bgp.rib.spi.BGPPeerTracker;
 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
@@ -51,6 +52,7 @@ import org.opendaylight.protocol.bgp.rib.spi.policy.BGPRibRoutingPolicy;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.BgpRib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.RibId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.Rib;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.RibKey;
@@ -105,6 +107,7 @@ public final class RIBImpl extends BGPRIBStateImpl implements RIB, TransactionCh
     private DOMTransactionChain domChain;
     @GuardedBy("this")
     private boolean isServiceInstantiated;
+    private Map<TablesKey, RibOutRefresh> vpnTableRefresher = new HashMap<>();
 
     public RIBImpl(
             final BGPTableTypeRegistryConsumer tableTypeRegistry,
@@ -191,6 +194,7 @@ public final class RIBImpl extends BGPRIBStateImpl implements RIB, TransactionCh
                 this.ribPolicies,
                 this.peerTracker,
                 pathSelectionStrategy);
+        this.vpnTableRefresher.put(key, locRibWriter);
         registerTotalPathCounter(key, locRibWriter);
         registerTotalPrefixesCounter(key, locRibWriter);
         this.txChainToLocRibWriter.put(txChain, locRibWriter);
@@ -269,6 +273,11 @@ public final class RIBImpl extends BGPRIBStateImpl implements RIB, TransactionCh
         return this.peerTracker;
     }
 
+    @Override
+    public void refreshTable(final TablesKey tk, final PeerId peerId) {
+        this.vpnTableRefresher.get(tk).refreshTable(tk, peerId);
+    }
+
     @Override
     public DOMDataTreeChangeService getService() {
         return (DOMDataTreeChangeService) this.domService;
diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RouteTargetMembeshipUtil.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RouteTargetMembeshipUtil.java
new file mode 100644 (file)
index 0000000..5a7893f
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.rib.impl;
+
+import java.util.Optional;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.Route;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.route.target.constrain.RouteTargetConstrainChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.route.target.constrain.route.target.constrain.choice.RouteTargetConstrainAs4ExtendedCommunityCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.route.target.constrain.route.target.constrain.choice.RouteTargetConstrainDefaultCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.route.target.constrain.route.target.constrain.choice.RouteTargetConstrainIpv4RouteCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.route.target.constrain.route.target.constrain.choice.RouteTargetConstrainRouteCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.route.target.constrain.rev180618.route.target.constrain.routes.route.target.constrain.routes.RouteTargetConstrainRoute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteTarget;
+
+/**
+ * @author Claudio D. Gasparini
+ */
+public final class RouteTargetMembeshipUtil {
+    private RouteTargetMembeshipUtil() {
+        throw new UnsupportedOperationException();
+    }
+
+    public static <R extends Route> Optional<RouteTarget> getRT(final R route) {
+        if (!(route instanceof RouteTargetConstrainRoute)) {
+            return Optional.empty();
+        }
+
+        final RouteTargetConstrainChoice rtc = ((RouteTargetConstrainRoute) route).getRouteTargetConstrainChoice();
+        RouteTarget rt;
+        if (rtc instanceof RouteTargetConstrainDefaultCase) {
+            rt = ((RouteTargetConstrainDefaultCase) rtc).getRouteTargetConstrainDefaultRoute();
+        } else if (rtc instanceof RouteTargetConstrainAs4ExtendedCommunityCase) {
+            rt = ((RouteTargetConstrainAs4ExtendedCommunityCase) rtc).getAs4RouteTargetExtendedCommunity();
+        } else if (rtc instanceof RouteTargetConstrainIpv4RouteCase) {
+            rt = ((RouteTargetConstrainIpv4RouteCase) rtc).getRouteTargetIpv4();
+        } else {
+            rt = ((RouteTargetConstrainRouteCase) rtc).getRouteTargetExtendedCommunity();
+        }
+        return Optional.of(rt);
+    }
+}
index 9d906553239d69848fe593bdf6ba05498231c4a1..adecec086744628c272d67c24a2f3147b547ec84 100644 (file)
@@ -47,6 +47,7 @@ import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.t
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.RibId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.Rib;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.RibKey;
@@ -288,4 +289,9 @@ public final class RibImpl implements RIB, BGPRibStateConsumer, AutoCloseable {
             this.ribImpl.instantiateServiceInstance();
         }
     }
+
+    @Override
+    public void refreshTable(final TablesKey tk, final PeerId peerId) {
+        this.ribImpl.refreshTable(tk, peerId);
+    }
 }
index 0164aefee081c5a1645dd0af0ca26fd861540dd1..643276cf7074d3e1d6e8348d653eeff6b8107a90 100755 (executable)
@@ -27,7 +27,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 /**
  * Internal reference to a RIB instance.
  */
-public interface RIB extends RibReference {
+public interface RIB extends RibReference, RibOutRefresh {
     /**
      * RIB AS.
      *
diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RibOutRefresh.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RibOutRefresh.java
new file mode 100644 (file)
index 0000000..fd22d66
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018 AT&T Intellectual Property. 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.rib.impl.spi;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
+
+/**
+ * Forces a reevaluation of paths and update on peer ribout.
+ */
+public interface RibOutRefresh {
+    /**
+     * Triggers the reevaluation.
+     *
+     * @param tk     table key of table route paths to be reevaluated
+     * @param peerId peer to advertize / withdraw paths after reevaluation
+     */
+    void refreshTable(TablesKey tk, PeerId peerId);
+}
index 7e44c9056f17f1b58034f85793b729db6ee0e8d1..9303641baf47f17383345c9b982a3bb540b834a4 100644 (file)
@@ -76,4 +76,16 @@ public interface Peer extends PeerTrackerInformation, RouteTargetMembershipConsu
             I extends Identifier<R>> void initializeRibOut(
             @Nonnull RouteEntryDependenciesContainer entryDep,
             @Nonnull List<ActualBestPathRoutes<C, S, R, I>> routes);
+
+    /**
+     * Applies all policies through all present routes, and advertize/withdraws based on new results.
+     * Scenario would be for example a removal of RT membership. And reprocess VPN routes.
+     *
+     * @param entryDep RouteEntryDependenciesContainer
+     * @param routes   routes to be updated.
+     */
+    <C extends Routes & DataObject & ChoiceIn<Tables>, S extends ChildOf<? super C>,
+            R extends Route & ChildOf<? super S> & Identifiable<I>,
+            I extends Identifier<R>> void reEvaluateAdvertizement(@Nonnull RouteEntryDependenciesContainer entryDep,
+            @Nonnull List<ActualBestPathRoutes<C, S, R, I>> routes);
 }