+ private void writeRoute(final DOMDataTreeWriteTransaction tx, final RIBSupport<?, ?, ?, ?> ribSupport,
+ final YangInstanceIdentifier routePath, final Optional<NormalizedNode<?, ?>> routeBefore,
+ final NormalizedNode<?, ?> routeAfter, final boolean longLivedStale) {
+ final TablesKey tablesKey = ribSupport.getTablesKey();
+ CountersUtil.increment(this.prefixesReceived.get(tablesKey), tablesKey);
+ // Lookup per-table attributes from RIBSupport
+ final ContainerNode advertisedAttrs = (ContainerNode) NormalizedNodes.findNode(routeAfter,
+ ribSupport.routeAttributesIdentifier()).orElse(null);
+ final Attributes routeAttrs = ribSupport.attributeFromContainerNode(advertisedAttrs);
+ final Optional<Attributes> optEffAtt;
+ // In case we want to add LLGR_STALE we do not process route through policies since it may be
+ // considered as received with LLGR_STALE from peer which is not true.
+ if (longLivedStale) {
+ // LLGR procedures are in effect. If the route is tagged with NO_LLGR, it needs to be removed.
+ final List<Communities> effCommunities = routeAttrs.getCommunities();
+ if (effCommunities != null && effCommunities.contains(CommunityUtil.NO_LLGR)) {
+ deleteRoute(tx, ribSupport, routePath, routeBefore.orElse(null));
+ return;
+ }
+ optEffAtt = Optional.of(wrapLongLivedStale(routeAttrs));
+ } else {
+ final Class<? extends AfiSafiType> afiSafiType
+ = tableTypeRegistry.getAfiSafiType(ribSupport.getTablesKey()).get();
+ optEffAtt = this.ribPolicies
+ .applyImportPolicies(this.peerImportParameters, routeAttrs, afiSafiType);
+ }
+ if (!optEffAtt.isPresent()) {
+ deleteRoute(tx, ribSupport, routePath, routeBefore.orElse(null));
+ return;
+ }
+ handleRouteTarget(ModificationType.WRITE, ribSupport, routePath, routeAfter);
+ tx.put(LogicalDatastoreType.OPERATIONAL, routePath, routeAfter);
+ CountersUtil.increment(this.prefixesInstalled.get(tablesKey), tablesKey);
+
+ final YangInstanceIdentifier attPath = routePath.node(ribSupport.routeAttributesIdentifier());
+ final Attributes attToStore = optEffAtt.get();
+ if (!attToStore.equals(routeAttrs)) {
+ final ContainerNode finalAttribute = ribSupport.attributeToContainerNode(attPath, attToStore);
+ tx.put(LogicalDatastoreType.OPERATIONAL, attPath, finalAttribute);
+ }
+ }
+
+ private void addRouteTarget(final RouteTargetConstrainRoute rtc) {
+ final RouteTarget rtMembership = RouteTargetMembeshipUtil.getRT(rtc);
+ if (PeerRole.Ebgp != this.peerImportParameters.getFromPeerRole()) {
+ this.rtCache.cacheRoute(rtc);
+ }
+ this.rtMemberships.add(rtMembership);
+ }
+
+ private void deleteRouteTarget(final RIBSupport<?, ?, ?, ?> ribSupport, final YangInstanceIdentifier routeIdPath,
+ final NormalizedNode<?, ?> route) {
+ deleteRouteTarget((RouteTargetConstrainRoute) ribSupport.fromNormalizedNode(routeIdPath, route));
+ }
+
+ private void deleteRouteTarget(final RouteTargetConstrainRoute rtc) {
+ final RouteTarget rtMembership = RouteTargetMembeshipUtil.getRT(rtc);
+ if (PeerRole.Ebgp != this.peerImportParameters.getFromPeerRole()) {
+ this.rtCache.uncacheRoute(rtc);
+ }
+ this.rtMemberships.remove(rtMembership);
+ }
+