2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.protocol.bgp.rib.impl;
10 import com.google.common.base.MoreObjects;
11 import com.google.common.base.MoreObjects.ToStringHelper;
12 import com.google.common.base.Optional;
13 import com.google.common.base.Preconditions;
14 import com.google.common.collect.ImmutableSet;
15 import com.google.common.util.concurrent.FutureCallback;
16 import com.google.common.util.concurrent.Futures;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.List;
21 import java.util.concurrent.BlockingQueue;
22 import java.util.concurrent.ConcurrentHashMap;
23 import java.util.concurrent.ConcurrentMap;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.LinkedBlockingQueue;
26 import javax.annotation.concurrent.ThreadSafe;
27 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
28 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
29 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
30 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
31 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
32 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
33 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
34 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
35 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
36 import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
37 import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
38 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
39 import org.opendaylight.protocol.bgp.rib.DefaultRibReference;
40 import org.opendaylight.protocol.bgp.rib.impl.spi.AdjRIBsOut;
41 import org.opendaylight.protocol.bgp.rib.impl.spi.AdjRIBsOutRegistration;
42 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
43 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
44 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
45 import org.opendaylight.protocol.bgp.rib.spi.AbstractAdjRIBs;
46 import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsIn;
47 import org.opendaylight.protocol.bgp.rib.spi.BGPObjectComparator;
48 import org.opendaylight.protocol.bgp.rib.spi.Peer;
49 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
50 import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.bgp.rib.rib.loc.rib.tables.routes.Ipv4RoutesCase;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.bgp.rib.rib.loc.rib.tables.routes.Ipv6RoutesCase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.DestinationIpv4Builder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.destination.ipv4.Ipv4Prefixes;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.destination.ipv4.Ipv4PrefixesBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.update.path.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationIpv4CaseBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.UpdateBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.Nlri;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributes;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.WithdrawnRoutes;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes2;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlri;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlriBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpUnreachNlri;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpUnreachNlriBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibKey;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRib;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRibBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
88 import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory;
89 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
90 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
91 import org.opendaylight.yangtools.yang.common.QName;
92 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
93 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
94 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
95 import org.slf4j.Logger;
96 import org.slf4j.LoggerFactory;
99 public final class RIBImpl extends DefaultRibReference implements AutoCloseable, RIB, TransactionChainListener, SchemaContextListener {
100 private static final Logger LOG = LoggerFactory.getLogger(RIBImpl.class);
101 private static final Update EOR = new UpdateBuilder().build();
102 private static final TablesKey IPV4_UNICAST_TABLE = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
103 private static final QName RIB_ID_QNAME = QName.cachedReference(QName.create(Rib.QNAME, "id"));
106 * FIXME: performance: this needs to be turned into a Peer->offset map.
107 * The offset is used to locate a the per-peer state entry in the
110 * For the first release, that map is updated whenever configuration
111 * changes and remains constant on peer flaps. On re-configuration
112 * a resize task is scheduled, so large tables may take some time
113 * before they continue reacting to updates.
115 * For subsequent releases, if we make the reformat process concurrent,
116 * we can trigger reformats when Graceful Restart Time expires for a
119 private final ConcurrentMap<Peer, AdjRIBsOut> ribOuts = new ConcurrentHashMap<>();
120 private final ReconnectStrategyFactory tcpStrategyFactory;
121 private final ReconnectStrategyFactory sessionStrategyFactory;
124 * BGP Best Path selection comparator for ingress best path selection.
126 private final BGPObjectComparator comparator;
127 private final BGPDispatcher dispatcher;
128 private final BindingTransactionChain chain;
129 private final AsNumber localAs;
130 private final Ipv4Address bgpIdentifier;
131 private final ClusterIdentifier clusterId;
132 private final Set<BgpTableType> localTables;
133 private final RIBTables tables;
134 private final BlockingQueue<Peer> peers;
135 private final DataBroker dataBroker;
136 private final DOMDataBroker domDataBroker;
137 private final RIBExtensionConsumerContext extensions;
138 private final YangInstanceIdentifier yangRibId;
139 private final RIBSupportContextRegistryImpl ribContextRegistry;
140 private final EffectiveRibInWriter efWriter;
142 private final Runnable scheduler = new Runnable() {
146 final Peer peer = RIBImpl.this.peers.take();
147 LOG.debug("Advertizing loc-rib to new peer {}.", peer);
148 for (final BgpTableType key : RIBImpl.this.localTables) {
150 synchronized (RIBImpl.this) {
151 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(RIBImpl.this.ribOuts, RIBImpl.this.comparator, RIBImpl.this.chain.newWriteOnlyTransaction());
152 final AbstractAdjRIBs<?, ?, ?> adj = (AbstractAdjRIBs<?, ?, ?>) RIBImpl.this.tables.get(new TablesKey(key.getAfi(), key.getSafi()));
153 adj.addAllEntries(trans);
154 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
156 public void onSuccess(final Void result) {
157 LOG.trace("Advertizing {} to peer {} committed successfully", key.getAfi(), peer);
160 public void onFailure(final Throwable t) {
161 LOG.error("Failed to update peer {} with RIB {}", peer, t);
166 } catch (final InterruptedException e) {
167 LOG.info("Scheduler thread was interrupted.", e);
172 public RIBImpl(final RibId ribId, final AsNumber localAs, final Ipv4Address localBgpId, final Ipv4Address clusterId, final RIBExtensionConsumerContext extensions,
173 final BGPDispatcher dispatcher, final ReconnectStrategyFactory tcpStrategyFactory, final BindingCodecTreeFactory codecFactory,
174 final ReconnectStrategyFactory sessionStrategyFactory, final DataBroker dps, final DOMDataBroker domDataBroker, final List<BgpTableType> localTables, final GeneratedClassLoadingStrategy classStrategy) {
175 super(InstanceIdentifier.create(BgpRib.class).child(Rib.class, new RibKey(Preconditions.checkNotNull(ribId))));
176 this.chain = dps.createTransactionChain(this);
177 this.localAs = Preconditions.checkNotNull(localAs);
178 this.comparator = new BGPObjectComparator(localAs);
179 this.bgpIdentifier = Preconditions.checkNotNull(localBgpId);
180 this.clusterId = (clusterId == null) ? new ClusterIdentifier(localBgpId) : new ClusterIdentifier(clusterId);
181 this.dispatcher = Preconditions.checkNotNull(dispatcher);
182 this.sessionStrategyFactory = Preconditions.checkNotNull(sessionStrategyFactory);
183 this.tcpStrategyFactory = Preconditions.checkNotNull(tcpStrategyFactory);
184 this.localTables = ImmutableSet.copyOf(localTables);
185 this.tables = new RIBTables(extensions);
186 this.peers = new LinkedBlockingQueue<>();
187 this.dataBroker = dps;
188 this.domDataBroker = Preconditions.checkNotNull(domDataBroker);
189 this.extensions = Preconditions.checkNotNull(extensions);
190 this.ribContextRegistry = RIBSupportContextRegistryImpl.create(extensions, codecFactory, classStrategy);
191 this.yangRibId = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Rib.QNAME).nodeWithKey(Rib.QNAME, RIB_ID_QNAME, ribId.getValue()).build();
193 LOG.debug("Instantiating RIB table {} at {}", ribId, getInstanceIdentifier());
195 final WriteTransaction trans = this.chain.newWriteOnlyTransaction();
197 // put empty BgpRib if not exists
198 trans.put(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier(),
199 new RibBuilder().setKey(new RibKey(ribId)).setPeer(Collections.<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer> emptyList()).setId(ribId).setLocRib(
200 new LocRibBuilder().setTables(Collections.<Tables> emptyList()).build()).build(), true);
202 for (final BgpTableType t : localTables) {
203 final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
204 if (this.tables.create(trans, this, key) == null) {
205 LOG.debug("Did not create local table for unhandled table type {}", t);
209 Futures.addCallback(trans.submit(), new FutureCallback<Void>() {
211 public void onSuccess(final Void result) {
212 LOG.trace("Change committed successfully");
216 public void onFailure(final Throwable t) {
217 LOG.error("Failed to initiate RIB {}", getInstanceIdentifier(), t);
222 final PolicyDatabase pd = new PolicyDatabase(localAs.getValue(), localBgpId, this.clusterId);
224 final DOMDataBrokerExtension service = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
225 final DOMTransactionChain domChain = this.createPeerChain(this);
226 this.efWriter = EffectiveRibInWriter.create((DOMDataTreeChangeService) service, this.createPeerChain(this), getYangRibId(), pd, this.ribContextRegistry);
227 LOG.debug("Effective RIB created.");
229 for (final BgpTableType t : localTables) {
230 final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
231 // create locRibWriter for each table
232 // FIXME: temporary create writer only for Ipv4
233 if (key.getAfi().equals(Ipv4AddressFamily.class) || key.getAfi().equals(Ipv6AddressFamily.class)) {
234 LocRibWriter.create(this.ribContextRegistry.getRIBSupportContext(key).getRibSupport(), key, this.createPeerChain(this), getYangRibId(), localAs, (DOMDataTreeChangeService) service, pd);
240 synchronized void initTables(final byte[] remoteBgpId) {
245 public synchronized void updateTables(final Peer peer, final Update message) {
246 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
248 if (!EOR.equals(message)) {
249 final WithdrawnRoutes wr = message.getWithdrawnRoutes();
251 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
254 * create MPUnreach for the routes to be handled in the same way as linkstate routes
256 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
257 for (final Ipv4Prefix p : wr.getWithdrawnRoutes()) {
258 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
263 new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).setWithdrawnRoutes(
264 new WithdrawnRoutesBuilder().setDestinationType(
265 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.update.path.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationIpv4CaseBuilder().setDestinationIpv4(
266 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build()).build());
268 LOG.debug("Not removing objects from unhandled IPv4 Unicast");
272 final PathAttributes attrs = message.getPathAttributes();
274 final PathAttributes2 mpu = attrs.getAugmentation(PathAttributes2.class);
276 final MpUnreachNlri nlri = mpu.getMpUnreachNlri();
277 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
278 // EOR messages do not contain withdrawn routes
279 if (nlri.getWithdrawnRoutes() != null) {
281 ari.removeRoutes(trans, peer, nlri);
283 LOG.debug("Not removing objects from unhandled NLRI {}", nlri);
286 ari.markUptodate(trans, peer);
291 final Nlri ar = message.getNlri();
293 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
296 * create MPReach for the routes to be handled in the same way as linkstate routes
298 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
299 for (final Ipv4Prefix p : ar.getNlri()) {
300 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
302 final MpReachNlriBuilder b = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(
303 UnicastSubsequentAddressFamily.class).setAdvertizedRoutes(
304 new AdvertizedRoutesBuilder().setDestinationType(
305 new DestinationIpv4CaseBuilder().setDestinationIpv4(
306 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build());
308 b.setCNextHop(attrs.getCNextHop());
311 ari.addRoutes(trans, peer, b.build(), attrs);
313 LOG.debug("Not adding objects from unhandled IPv4 Unicast");
318 final PathAttributes1 mpr = attrs.getAugmentation(PathAttributes1.class);
320 final MpReachNlri nlri = mpr.getMpReachNlri();
322 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
324 if (message.equals(ari.endOfRib())) {
325 ari.markUptodate(trans, peer);
327 ari.addRoutes(trans, peer, nlri, attrs);
330 LOG.debug("Not adding objects from unhandled NLRI {}", nlri);
335 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
337 ari.markUptodate(trans, peer);
339 LOG.debug("End-of-RIB for IPv4 Unicast ignored");
343 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
345 public void onSuccess(final Void result) {
346 LOG.debug("RIB modification successfully committed.");
350 public void onFailure(final Throwable t) {
351 LOG.error("Failed to commit RIB modification", t);
358 public synchronized void clearTable(final Peer peer, final TablesKey key) {
359 final AdjRIBsIn<?, ?> ari = this.tables.get(key);
361 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
362 ari.clear(trans, peer);
364 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
366 public void onSuccess(final Void result) {
367 LOG.trace("Table {} cleared successfully", key);
371 public void onFailure(final Throwable t) {
372 LOG.error("Failed to clear table {}", key, t);
379 public String toString() {
380 return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
383 protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
384 return toStringHelper;
387 @SuppressWarnings("unchecked")
389 protected <K, V extends Route> AdjRIBsIn<K, V> getTable(final TablesKey key) {
390 return (AdjRIBsIn<K, V>) this.tables.get(key);
394 public synchronized void close() throws InterruptedException, ExecutionException {
395 final WriteTransaction t = this.chain.newWriteOnlyTransaction();
396 t.delete(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier());
402 public AsNumber getLocalAs() {
407 public Ipv4Address getBgpIdentifier() {
408 return this.bgpIdentifier;
412 public Set<? extends BgpTableType> getLocalTables() {
413 return this.localTables;
417 public ReconnectStrategyFactory getTcpStrategyFactory() {
418 return this.tcpStrategyFactory;
422 public ReconnectStrategyFactory getSessionStrategyFactory() {
423 return this.sessionStrategyFactory;
427 public BGPDispatcher getDispatcher() {
428 return this.dispatcher;
433 public void initTable(final Peer bgpPeer, final TablesKey key) {
434 // FIXME: BUG-196: support graceful restart
438 public AdjRIBsOutRegistration registerRIBsOut(final Peer peer, final AdjRIBsOut aro) {
439 final AdjRIBsOutRegistration reg = new AdjRIBsOutRegistration(aro) {
441 protected void removeRegistration() {
442 RIBImpl.this.ribOuts.remove(peer, aro);
446 this.ribOuts.put(peer, aro);
447 LOG.debug("Registering this peer {} to RIB-Out {}", peer, this.ribOuts);
449 this.peers.put(peer);
450 new Thread(this.scheduler).start();
451 } catch (final InterruptedException e) {
458 public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction, final Throwable cause) {
459 LOG.error("Broken chain in RIB {} transaction {}", getInstanceIdentifier(), transaction.getIdentifier(), cause);
463 public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
464 LOG.info("RIB {} closed successfully", getInstanceIdentifier());
468 public long getRoutesCount(final TablesKey key) {
470 final Optional<Tables> tableMaybe = this.dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL,
471 getInstanceIdentifier().child(LocRib.class).child(Tables.class, key)).checkedGet();
472 if (tableMaybe.isPresent()) {
473 final Tables table = tableMaybe.get();
474 if (table.getRoutes() instanceof Ipv4RoutesCase) {
475 final Ipv4RoutesCase routesCase = (Ipv4RoutesCase) table.getRoutes();
476 if (routesCase.getIpv4Routes() != null && routesCase.getIpv4Routes().getIpv4Route() != null) {
477 return routesCase.getIpv4Routes().getIpv4Route().size();
479 } else if (table.getRoutes() instanceof Ipv6RoutesCase) {
480 final Ipv6RoutesCase routesCase = (Ipv6RoutesCase) table.getRoutes();
481 if (routesCase.getIpv6Routes() != null && routesCase.getIpv6Routes().getIpv6Route() != null) {
482 return routesCase.getIpv6Routes().getIpv6Route().size();
486 } catch (final ReadFailedException e) {
493 public YangInstanceIdentifier getYangRibId() {
494 return this.yangRibId;
498 public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
499 return this.domDataBroker.createTransactionChain(listener);
503 public RIBExtensionConsumerContext getRibExtensions() {
504 return this.extensions;
508 public RIBSupportContextRegistry getRibSupportContext() {
509 return this.ribContextRegistry;
513 public void onGlobalContextUpdated(final SchemaContext context) {
514 this.ribContextRegistry.onSchemaContextUpdated(context);