BUG-4714 : No routes from loc-rib are advertised 17/32417/7
authorClaudio D. Gasparini <cgaspari@cisco.com>
Tue, 12 Jan 2016 12:25:53 +0000 (13:25 +0100)
committerClaudio D. Gasparini <cgaspari@cisco.com>
Thu, 14 Jan 2016 11:15:02 +0000 (12:15 +0100)
When new peer connects, already existent routes on EffectiveRibIn
Table are not advertised and stored on corresponding AdjRibOut
Peer table. Therefore AdjRiboutListener doesnt advertise
these routes.
Fix by apply routes, when supported tables are created.

Change-Id: Id263723ee685bbc61468e1ea532f0f57f1c6c6c7
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ExportPolicyPeerTracker.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/RouterIds.java

index 227b2ec75adeda4c072e863f4b675e117dc33875..69b67656105e96992c3415dc111a6f8aa11a4741 100644 (file)
@@ -105,19 +105,25 @@ final class ExportPolicyPeerTracker extends AbstractPeerRoleTracker {
         return this.groups.get(Preconditions.checkNotNull(role));
     }
 
-    void onTablesChanged(final PeerId peerId, final DataTreeCandidateNode node) {
+    boolean onTablesChanged(final PeerId peerId, final DataTreeCandidateNode node) {
         if (node.getDataAfter().isPresent()) {
             final NodeIdentifierWithPredicates value = (NodeIdentifierWithPredicates) node.getDataAfter().get().getIdentifier();
             final boolean added = this.peerTables.put(peerId, value);
             if (added) {
                 LOG.debug("Supported table {} added to peer {}", value, peerId);
             }
+            return added;
         } else {
             LOG.debug("Removed tables {} from peer {}", this.peerTables.removeAll(peerId), peerId);
         }
+        return false;
     }
 
     boolean isTableSupported(final PeerId peerId, final TablesKey tablesKey) {
         return this.peerTables.get(peerId).contains(RibSupportUtils.toYangKey(SupportedTables.QNAME, tablesKey));
     }
+
+    public PeerRole getRole(final YangInstanceIdentifier peerId) {
+        return this.peerRoles.get(peerId);
+    }
 }
\ No newline at end of file
index 48b724d221878b8625ed76ee020f6a5dd9853c12..981307e1acce4119c4a698145d67d167696ea904 100644 (file)
@@ -75,7 +75,7 @@ final class LocRibWriter implements AutoCloseable, DOMDataTreeChangeListener {
     private final RIBSupportContextRegistry registry;
     private final ListenerRegistration<LocRibWriter> reg;
 
-    LocRibWriter(final RIBSupportContextRegistry registry, final DOMTransactionChain chain, final YangInstanceIdentifier target, final Long ourAs,
+    private LocRibWriter(final RIBSupportContextRegistry registry, final DOMTransactionChain chain, final YangInstanceIdentifier target, final Long ourAs,
         final DOMDataTreeChangeService service, final PolicyDatabase pd, final TablesKey tablesKey) {
         this.chain = Preconditions.checkNotNull(chain);
         this.tableKey = RibSupportUtils.toYangTablesKey(tablesKey);
@@ -185,12 +185,38 @@ final class LocRibWriter implements AutoCloseable, DOMDataTreeChangeListener {
 
         if (tablesChange != null) {
             final PeerId peerIdOfNewPeer = IdentifierUtils.peerId((NodeIdentifierWithPredicates) IdentifierUtils.peerPath(rootPath).getLastPathArgument());
+            final PeerRole newPeerRole = this.peerPolicyTracker.getRole(IdentifierUtils.peerPath(rootPath));
+            final PeerExportGroup peerGroup = this.peerPolicyTracker.getPeerGroup(newPeerRole);
+
             for (final DataTreeCandidateNode node : tablesChange.getChildNodes()) {
-                this.peerPolicyTracker.onTablesChanged(peerIdOfNewPeer, node);
+                final boolean supportedTableAdded = this.peerPolicyTracker.onTablesChanged(peerIdOfNewPeer, node);
+                if (supportedTableAdded) {
+                    for (Map.Entry<PathArgument, AbstractRouteEntry> entry : this.routeEntries.entrySet()) {
+                        if(isTableSupported(peerIdOfNewPeer)) {
+                            final AbstractRouteEntry routeEntry = entry.getValue();
+                            final ContainerNode attributes = routeEntry.attributes();
+                            final PathArgument routeId = entry.getKey();
+                            final YangInstanceIdentifier routeTarget = getRouteTarget(rootPath, routeId);
+                            final NormalizedNode<?, ?> value = routeEntry.createValue(routeId);
+                            final PeerId routePeerId = RouterIds.createPeerId(routeEntry.getBestRouterId());
+                            final ContainerNode effectiveAttributes = peerGroup.effectiveAttributes(routePeerId, attributes);
+
+                            if (effectiveAttributes != null && value != null) {
+                                LOG.debug("Write route {} to peer AdjRibsOut {}", value, peerIdOfNewPeer);
+                                tx.put(LogicalDatastoreType.OPERATIONAL, routeTarget, value);
+                                tx.put(LogicalDatastoreType.OPERATIONAL, routeTarget.node(this.attributesIdentifier), effectiveAttributes);
+                            }
+                        }
+                    }
+                }
             }
         }
     }
 
+    private YangInstanceIdentifier getRouteTarget(final YangInstanceIdentifier rootPath, final PathArgument routeId) {
+        return this.ribSupport.routePath(rootPath.node(AdjRibOut.QNAME).node(Tables.QNAME).node(this.tableKey).node(ROUTES_IDENTIFIER), routeId);
+    }
+
     private void filterOutPeerRole(final DataTreeCandidateNode rootNode, final YangInstanceIdentifier rootPath) {
         final DataTreeCandidateNode roleChange = rootNode.getModifiedChild(AbstractPeerRoleTracker.PEER_ROLE_NID);
         if (roleChange != null) {
@@ -267,7 +293,7 @@ final class LocRibWriter implements AutoCloseable, DOMDataTreeChangeListener {
     }
 
     @VisibleForTesting
-    void fillAdjRibsOut(final DOMDataWriteTransaction tx, final AbstractRouteEntry entry, final NormalizedNode<?, ?> value, final RouteUpdateKey key) {
+    private void fillAdjRibsOut(final DOMDataWriteTransaction tx, final AbstractRouteEntry entry, final NormalizedNode<?, ?> value, final RouteUpdateKey key) {
         /*
          * We need to keep track of routers and populate adj-ribs-out, too. If we do not, we need to
          * expose from which client a particular route was learned from in the local RIB, and have
@@ -280,17 +306,12 @@ final class LocRibWriter implements AutoCloseable, DOMDataTreeChangeListener {
         for (final PeerRole role : PeerRole.values()) {
             final PeerExportGroup peerGroup = this.peerPolicyTracker.getPeerGroup(role);
             if (peerGroup != null) {
-                final ContainerNode attributes = entry == null ? null : entry.attributes();
                 final PeerId peerId = key.getPeerId();
-                final ContainerNode effectiveAttributes = peerGroup.effectiveAttributes(peerId, attributes);
+                final ContainerNode effectiveAttributes = peerGroup.effectiveAttributes(peerId, entry.attributes());
                 if (effectiveAttributes != null) {
                     for (final Entry<PeerId, YangInstanceIdentifier> pid : peerGroup.getPeers()) {
-                        if (!peerId.equals(pid.getKey())) {
-                            if (!this.peerPolicyTracker.isTableSupported(pid.getKey(), this.localTablesKey)) {
-                                LOG.trace("Route rejected, peer {} does not support this table type {}", pid.getKey(), this.localTablesKey);
-                                continue;
-                            }
-                            final YangInstanceIdentifier routeTarget = this.ribSupport.routePath(pid.getValue().node(AdjRibOut.QNAME).node(Tables.QNAME).node(this.tableKey).node(ROUTES_IDENTIFIER), key.getRouteId());
+                        if (!peerId.equals(pid.getKey()) && isTableSupported(pid.getKey())) {
+                            final YangInstanceIdentifier routeTarget = getRouteTarget(pid.getValue(), key.getRouteId());
                             if (value != null) {
                                 LOG.debug("Write route {} to peers AdjRibsOut {}", value, pid.getKey());
                                 tx.put(LogicalDatastoreType.OPERATIONAL, routeTarget, value);
@@ -305,4 +326,12 @@ final class LocRibWriter implements AutoCloseable, DOMDataTreeChangeListener {
             }
         }
     }
+
+    private boolean isTableSupported(final PeerId key) {
+        if (!this.peerPolicyTracker.isTableSupported(key, this.localTablesKey)) {
+            LOG.trace("Route rejected, peer {} does not support this table type {}", key, this.localTablesKey);
+            return false;
+        }
+        return true;
+    }
 }
index 47237d4ab7a8004d9ddd3703a80aea0729463dc4..bc6b3977984bb61b8699d957c6c3fc6c8c311337 100644 (file)
@@ -55,4 +55,9 @@ final class RouterIds {
     public static PeerId createPeerId(@Nonnull final Ipv4Address address) {
         return new PeerId(BGP_PREFIX + address.getValue());
     }
+
+    public static PeerId createPeerId(@Nonnull final UnsignedInteger intAddress) {
+        final String inet4Address = InetAddresses.fromInteger(intAddress.intValue()).getHostAddress();
+        return new PeerId(BGP_PREFIX.concat(inet4Address));
+    }
 }