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.UnicastSubsequentAddressFamily;
87 import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory;
88 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
89 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
90 import org.opendaylight.yangtools.yang.common.QName;
91 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
92 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
93 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
94 import org.slf4j.Logger;
95 import org.slf4j.LoggerFactory;
98 public final class RIBImpl extends DefaultRibReference implements AutoCloseable, RIB, TransactionChainListener, SchemaContextListener {
99 private static final Logger LOG = LoggerFactory.getLogger(RIBImpl.class);
100 private static final Update EOR = new UpdateBuilder().build();
101 private static final TablesKey IPV4_UNICAST_TABLE = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
102 private static final QName RIB_ID_QNAME = QName.cachedReference(QName.create(Rib.QNAME, "id"));
105 * FIXME: performance: this needs to be turned into a Peer->offset map.
106 * The offset is used to locate a the per-peer state entry in the
109 * For the first release, that map is updated whenever configuration
110 * changes and remains constant on peer flaps. On re-configuration
111 * a resize task is scheduled, so large tables may take some time
112 * before they continue reacting to updates.
114 * For subsequent releases, if we make the reformat process concurrent,
115 * we can trigger reformats when Graceful Restart Time expires for a
118 private final ConcurrentMap<Peer, AdjRIBsOut> ribOuts = new ConcurrentHashMap<>();
119 private final ReconnectStrategyFactory tcpStrategyFactory;
120 private final ReconnectStrategyFactory sessionStrategyFactory;
123 * BGP Best Path selection comparator for ingress best path selection.
125 private final BGPObjectComparator comparator;
126 private final BGPDispatcher dispatcher;
127 private final BindingTransactionChain chain;
128 private final AsNumber localAs;
129 private final Ipv4Address bgpIdentifier;
130 private final Ipv4Address clusterId;
131 private final Set<BgpTableType> localTables;
132 private final RIBTables tables;
133 private final BlockingQueue<Peer> peers;
134 private final DataBroker dataBroker;
135 private final DOMDataBroker domDataBroker;
136 private final RIBExtensionConsumerContext extensions;
137 private final YangInstanceIdentifier yangRibId;
138 private final RIBSupportContextRegistryImpl ribContextRegistry;
139 private final Runnable scheduler = new Runnable() {
143 final Peer peer = RIBImpl.this.peers.take();
144 LOG.debug("Advertizing loc-rib to new peer {}.", peer);
145 for (final BgpTableType key : RIBImpl.this.localTables) {
147 synchronized (RIBImpl.this) {
148 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(RIBImpl.this.ribOuts, RIBImpl.this.comparator, RIBImpl.this.chain.newWriteOnlyTransaction());
149 final AbstractAdjRIBs<?, ?, ?> adj = (AbstractAdjRIBs<?, ?, ?>) RIBImpl.this.tables.get(new TablesKey(key.getAfi(), key.getSafi()));
150 adj.addAllEntries(trans);
151 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
153 public void onSuccess(final Void result) {
154 LOG.trace("Advertizing {} to peer {} committed successfully", key.getAfi(), peer);
157 public void onFailure(final Throwable t) {
158 LOG.error("Failed to update peer {} with RIB {}", peer, t);
163 } catch (final InterruptedException e) {
164 LOG.info("Scheduler thread was interrupted.", e);
169 public RIBImpl(final RibId ribId, final AsNumber localAs, final Ipv4Address localBgpId, final Ipv4Address clusterId, final RIBExtensionConsumerContext extensions,
170 final BGPDispatcher dispatcher, final ReconnectStrategyFactory tcpStrategyFactory, final BindingCodecTreeFactory codecFactory,
171 final ReconnectStrategyFactory sessionStrategyFactory, final DataBroker dps, final DOMDataBroker domDataBroker, final List<BgpTableType> localTables, GeneratedClassLoadingStrategy classStrategy) {
172 super(InstanceIdentifier.create(BgpRib.class).child(Rib.class, new RibKey(Preconditions.checkNotNull(ribId))));
173 this.chain = dps.createTransactionChain(this);
174 this.localAs = Preconditions.checkNotNull(localAs);
175 this.comparator = new BGPObjectComparator(localAs);
176 this.bgpIdentifier = Preconditions.checkNotNull(localBgpId);
177 this.clusterId = clusterId == null ? localBgpId : clusterId;
178 this.dispatcher = Preconditions.checkNotNull(dispatcher);
179 this.sessionStrategyFactory = Preconditions.checkNotNull(sessionStrategyFactory);
180 this.tcpStrategyFactory = Preconditions.checkNotNull(tcpStrategyFactory);
181 this.localTables = ImmutableSet.copyOf(localTables);
182 this.tables = new RIBTables(extensions);
183 this.peers = new LinkedBlockingQueue<>();
184 this.dataBroker = dps;
185 this.domDataBroker = Preconditions.checkNotNull(domDataBroker);
186 this.extensions = Preconditions.checkNotNull(extensions);
187 this.ribContextRegistry = RIBSupportContextRegistryImpl.create(extensions, codecFactory, classStrategy);
188 this.yangRibId = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Rib.QNAME).nodeWithKey(Rib.QNAME, RIB_ID_QNAME, ribId.getValue()).build();
190 LOG.debug("Instantiating RIB table {} at {}", ribId, getInstanceIdentifier());
192 final WriteTransaction trans = this.chain.newWriteOnlyTransaction();
194 final PolicyDatabase pd = new PolicyDatabase(localAs.getValue(), localBgpId, new ClusterIdentifier(localBgpId));
195 /*if (clusterId == null) {
196 clusterId is not present, fallback to bgpId
197 pd = new PolicyDatabase(localAs.getValue(), localBgpId, new ClusterIdentifier(localBgpId));
199 pd = new PolicyDatabase(as, bgpId, clusterId);
202 final DOMDataBrokerExtension service = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
203 final DOMTransactionChain domChain = this.createPeerChain(this);
205 EffectiveRibInWriter.create((DOMDataTreeChangeService) service, domChain, getYangRibId(), pd, this.ribContextRegistry);
207 // put empty BgpRib if not exists
208 trans.put(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier(),
209 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(
210 new LocRibBuilder().setTables(Collections.<Tables> emptyList()).build()).build(), true);
212 for (final BgpTableType t : localTables) {
213 final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
214 if (this.tables.create(trans, this, key) == null) {
215 LOG.debug("Did not create local table for unhandled table type {}", t);
218 // reusing the for cycle
219 // create locRibWriter for each table
220 // FIXME: temporary create writer only for Ipv4
221 if (key.getAfi().equals(Ipv4AddressFamily.class)) {
222 LocRibWriter.create(this.ribContextRegistry.getRIBSupportContext(key).getRibSupport(), domChain, getYangRibId(), localAs, (DOMDataTreeChangeService) service, pd);
226 Futures.addCallback(trans.submit(), new FutureCallback<Void>() {
228 public void onSuccess(final Void result) {
229 LOG.trace("Change committed successfully");
233 public void onFailure(final Throwable t) {
234 LOG.error("Failed to initiate RIB {}", getInstanceIdentifier(), t);
240 synchronized void initTables(final byte[] remoteBgpId) {
244 public synchronized void updateTables(final Peer peer, final Update message) {
245 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
247 if (!EOR.equals(message)) {
248 final WithdrawnRoutes wr = message.getWithdrawnRoutes();
250 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
253 * create MPUnreach for the routes to be handled in the same way as linkstate routes
255 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
256 for (final Ipv4Prefix p : wr.getWithdrawnRoutes()) {
257 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
262 new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).setWithdrawnRoutes(
263 new WithdrawnRoutesBuilder().setDestinationType(
264 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(
265 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build()).build());
267 LOG.debug("Not removing objects from unhandled IPv4 Unicast");
271 final PathAttributes attrs = message.getPathAttributes();
273 final PathAttributes2 mpu = attrs.getAugmentation(PathAttributes2.class);
275 final MpUnreachNlri nlri = mpu.getMpUnreachNlri();
276 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
277 // EOR messages do not contain withdrawn routes
278 if (nlri.getWithdrawnRoutes() != null) {
280 ari.removeRoutes(trans, peer, nlri);
282 LOG.debug("Not removing objects from unhandled NLRI {}", nlri);
285 ari.markUptodate(trans, peer);
290 final Nlri ar = message.getNlri();
292 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
295 * create MPReach for the routes to be handled in the same way as linkstate routes
297 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
298 for (final Ipv4Prefix p : ar.getNlri()) {
299 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
301 final MpReachNlriBuilder b = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(
302 UnicastSubsequentAddressFamily.class).setAdvertizedRoutes(
303 new AdvertizedRoutesBuilder().setDestinationType(
304 new DestinationIpv4CaseBuilder().setDestinationIpv4(
305 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build());
307 b.setCNextHop(attrs.getCNextHop());
310 ari.addRoutes(trans, peer, b.build(), attrs);
312 LOG.debug("Not adding objects from unhandled IPv4 Unicast");
317 final PathAttributes1 mpr = attrs.getAugmentation(PathAttributes1.class);
319 final MpReachNlri nlri = mpr.getMpReachNlri();
321 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
323 if (message.equals(ari.endOfRib())) {
324 ari.markUptodate(trans, peer);
326 ari.addRoutes(trans, peer, nlri, attrs);
329 LOG.debug("Not adding objects from unhandled NLRI {}", nlri);
334 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
336 ari.markUptodate(trans, peer);
338 LOG.debug("End-of-RIB for IPv4 Unicast ignored");
342 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
344 public void onSuccess(final Void result) {
345 LOG.debug("RIB modification successfully committed.");
349 public void onFailure(final Throwable t) {
350 LOG.error("Failed to commit RIB modification", t);
356 public synchronized void clearTable(final Peer peer, final TablesKey key) {
357 final AdjRIBsIn<?, ?> ari = this.tables.get(key);
359 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
360 ari.clear(trans, peer);
362 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
364 public void onSuccess(final Void result) {
365 LOG.trace("Table {} cleared successfully", key);
369 public void onFailure(final Throwable t) {
370 LOG.error("Failed to clear table {}", key, t);
377 public String toString() {
378 return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
381 protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
382 return toStringHelper;
385 @SuppressWarnings("unchecked")
386 protected <K, V extends Route> AdjRIBsIn<K, V> getTable(final TablesKey key) {
387 return (AdjRIBsIn<K, V>) this.tables.get(key);
391 public synchronized void close() throws InterruptedException, ExecutionException {
392 final WriteTransaction t = this.chain.newWriteOnlyTransaction();
393 t.delete(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier());
399 public AsNumber getLocalAs() {
404 public Ipv4Address getBgpIdentifier() {
405 return this.bgpIdentifier;
409 public Set<? extends BgpTableType> getLocalTables() {
410 return this.localTables;
414 public ReconnectStrategyFactory getTcpStrategyFactory() {
415 return this.tcpStrategyFactory;
419 public ReconnectStrategyFactory getSessionStrategyFactory() {
420 return this.sessionStrategyFactory;
424 public BGPDispatcher getDispatcher() {
425 return this.dispatcher;
429 public void initTable(final Peer bgpPeer, final TablesKey key) {
430 // FIXME: BUG-196: support graceful restart
434 public AdjRIBsOutRegistration registerRIBsOut(final Peer peer, final AdjRIBsOut aro) {
435 final AdjRIBsOutRegistration reg = new AdjRIBsOutRegistration(aro) {
437 protected void removeRegistration() {
438 RIBImpl.this.ribOuts.remove(peer, aro);
442 this.ribOuts.put(peer, aro);
443 LOG.debug("Registering this peer {} to RIB-Out {}", peer, this.ribOuts);
445 this.peers.put(peer);
446 new Thread(this.scheduler).start();
447 } catch (final InterruptedException e) {
454 public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction, final Throwable cause) {
455 LOG.error("Broken chain in RIB {} transaction {}", getInstanceIdentifier(), transaction.getIdentifier(), cause);
459 public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
460 LOG.info("RIB {} closed successfully", getInstanceIdentifier());
464 public long getRoutesCount(final TablesKey key) {
466 final Optional<Tables> tableMaybe = this.dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL,
467 getInstanceIdentifier().child(LocRib.class).child(Tables.class, key)).checkedGet();
468 if (tableMaybe.isPresent()) {
469 final Tables table = tableMaybe.get();
470 if (table.getRoutes() instanceof Ipv4RoutesCase) {
471 final Ipv4RoutesCase routesCase = (Ipv4RoutesCase) table.getRoutes();
472 if (routesCase.getIpv4Routes() != null && routesCase.getIpv4Routes().getIpv4Route() != null) {
473 return routesCase.getIpv4Routes().getIpv4Route().size();
475 } else if (table.getRoutes() instanceof Ipv6RoutesCase) {
476 final Ipv6RoutesCase routesCase = (Ipv6RoutesCase) table.getRoutes();
477 if (routesCase.getIpv6Routes() != null && routesCase.getIpv6Routes().getIpv6Route() != null) {
478 return routesCase.getIpv6Routes().getIpv6Route().size();
482 } catch (final ReadFailedException e) {
489 public YangInstanceIdentifier getYangRibId() {
490 return this.yangRibId;
494 public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
495 return this.domDataBroker.createTransactionChain(listener);
499 public RIBExtensionConsumerContext getRibExtensions() {
500 return this.extensions;
504 public RIBSupportContextRegistry getRibSupportContext() {
505 return this.ribContextRegistry;
509 public void onGlobalContextUpdated(final SchemaContext context) {
510 this.ribContextRegistry.onSchemaContextUpdated(context);