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 ClusterIdentifier 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 EffectiveRibInWriter efWriter;
141 private final Runnable scheduler = new Runnable() {
145 final Peer peer = RIBImpl.this.peers.take();
146 LOG.debug("Advertizing loc-rib to new peer {}.", peer);
147 for (final BgpTableType key : RIBImpl.this.localTables) {
149 synchronized (RIBImpl.this) {
150 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(RIBImpl.this.ribOuts, RIBImpl.this.comparator, RIBImpl.this.chain.newWriteOnlyTransaction());
151 final AbstractAdjRIBs<?, ?, ?> adj = (AbstractAdjRIBs<?, ?, ?>) RIBImpl.this.tables.get(new TablesKey(key.getAfi(), key.getSafi()));
152 adj.addAllEntries(trans);
153 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
155 public void onSuccess(final Void result) {
156 LOG.trace("Advertizing {} to peer {} committed successfully", key.getAfi(), peer);
159 public void onFailure(final Throwable t) {
160 LOG.error("Failed to update peer {} with RIB {}", peer, t);
165 } catch (final InterruptedException e) {
166 LOG.info("Scheduler thread was interrupted.", e);
171 public RIBImpl(final RibId ribId, final AsNumber localAs, final Ipv4Address localBgpId, final Ipv4Address clusterId, final RIBExtensionConsumerContext extensions,
172 final BGPDispatcher dispatcher, final ReconnectStrategyFactory tcpStrategyFactory, final BindingCodecTreeFactory codecFactory,
173 final ReconnectStrategyFactory sessionStrategyFactory, final DataBroker dps, final DOMDataBroker domDataBroker, final List<BgpTableType> localTables, final GeneratedClassLoadingStrategy classStrategy) {
174 super(InstanceIdentifier.create(BgpRib.class).child(Rib.class, new RibKey(Preconditions.checkNotNull(ribId))));
175 this.chain = dps.createTransactionChain(this);
176 this.localAs = Preconditions.checkNotNull(localAs);
177 this.comparator = new BGPObjectComparator(localAs);
178 this.bgpIdentifier = Preconditions.checkNotNull(localBgpId);
179 this.clusterId = (clusterId == null) ? new ClusterIdentifier(localBgpId) : new ClusterIdentifier(clusterId);
180 this.dispatcher = Preconditions.checkNotNull(dispatcher);
181 this.sessionStrategyFactory = Preconditions.checkNotNull(sessionStrategyFactory);
182 this.tcpStrategyFactory = Preconditions.checkNotNull(tcpStrategyFactory);
183 this.localTables = ImmutableSet.copyOf(localTables);
184 this.tables = new RIBTables(extensions);
185 this.peers = new LinkedBlockingQueue<>();
186 this.dataBroker = dps;
187 this.domDataBroker = Preconditions.checkNotNull(domDataBroker);
188 this.extensions = Preconditions.checkNotNull(extensions);
189 this.ribContextRegistry = RIBSupportContextRegistryImpl.create(extensions, codecFactory, classStrategy);
190 this.yangRibId = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Rib.QNAME).nodeWithKey(Rib.QNAME, RIB_ID_QNAME, ribId.getValue()).build();
192 LOG.debug("Instantiating RIB table {} at {}", ribId, getInstanceIdentifier());
194 final WriteTransaction trans = this.chain.newWriteOnlyTransaction();
196 // put empty BgpRib if not exists
197 trans.put(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier(),
198 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(
199 new LocRibBuilder().setTables(Collections.<Tables> emptyList()).build()).build(), true);
201 for (final BgpTableType t : localTables) {
202 final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
203 if (this.tables.create(trans, this, key) == null) {
204 LOG.debug("Did not create local table for unhandled table type {}", t);
208 Futures.addCallback(trans.submit(), new FutureCallback<Void>() {
210 public void onSuccess(final Void result) {
211 LOG.trace("Change committed successfully");
215 public void onFailure(final Throwable t) {
216 LOG.error("Failed to initiate RIB {}", getInstanceIdentifier(), t);
221 final PolicyDatabase pd = new PolicyDatabase(localAs.getValue(), localBgpId, this.clusterId);
223 final DOMDataBrokerExtension service = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
224 final DOMTransactionChain domChain = this.createPeerChain(this);
225 this.efWriter = EffectiveRibInWriter.create((DOMDataTreeChangeService) service, domChain, getYangRibId(), pd, this.ribContextRegistry);
226 LOG.debug("Effective RIB created.");
228 for (final BgpTableType t : localTables) {
229 final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
230 // create locRibWriter for each table
231 // FIXME: temporary create writer only for Ipv4
232 if (key.getAfi().equals(Ipv4AddressFamily.class)) {
233 LocRibWriter.create(this.ribContextRegistry.getRIBSupportContext(key).getRibSupport(), key, domChain, getYangRibId(), localAs, (DOMDataTreeChangeService) service, pd);
239 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);
357 public synchronized void clearTable(final Peer peer, final TablesKey key) {
358 final AdjRIBsIn<?, ?> ari = this.tables.get(key);
360 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
361 ari.clear(trans, peer);
363 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
365 public void onSuccess(final Void result) {
366 LOG.trace("Table {} cleared successfully", key);
370 public void onFailure(final Throwable t) {
371 LOG.error("Failed to clear table {}", key, t);
378 public String toString() {
379 return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
382 protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
383 return toStringHelper;
386 @SuppressWarnings("unchecked")
388 protected <K, V extends Route> AdjRIBsIn<K, V> getTable(final TablesKey key) {
389 return (AdjRIBsIn<K, V>) this.tables.get(key);
393 public synchronized void close() throws InterruptedException, ExecutionException {
394 final WriteTransaction t = this.chain.newWriteOnlyTransaction();
395 t.delete(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier());
401 public AsNumber getLocalAs() {
406 public Ipv4Address getBgpIdentifier() {
407 return this.bgpIdentifier;
411 public Set<? extends BgpTableType> getLocalTables() {
412 return this.localTables;
416 public ReconnectStrategyFactory getTcpStrategyFactory() {
417 return this.tcpStrategyFactory;
421 public ReconnectStrategyFactory getSessionStrategyFactory() {
422 return this.sessionStrategyFactory;
426 public BGPDispatcher getDispatcher() {
427 return this.dispatcher;
432 public void initTable(final Peer bgpPeer, final TablesKey key) {
433 // FIXME: BUG-196: support graceful restart
437 public AdjRIBsOutRegistration registerRIBsOut(final Peer peer, final AdjRIBsOut aro) {
438 final AdjRIBsOutRegistration reg = new AdjRIBsOutRegistration(aro) {
440 protected void removeRegistration() {
441 RIBImpl.this.ribOuts.remove(peer, aro);
445 this.ribOuts.put(peer, aro);
446 LOG.debug("Registering this peer {} to RIB-Out {}", peer, this.ribOuts);
448 this.peers.put(peer);
449 new Thread(this.scheduler).start();
450 } catch (final InterruptedException e) {
457 public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction, final Throwable cause) {
458 LOG.error("Broken chain in RIB {} transaction {}", getInstanceIdentifier(), transaction.getIdentifier(), cause);
462 public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
463 LOG.info("RIB {} closed successfully", getInstanceIdentifier());
467 public long getRoutesCount(final TablesKey key) {
469 final Optional<Tables> tableMaybe = this.dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL,
470 getInstanceIdentifier().child(LocRib.class).child(Tables.class, key)).checkedGet();
471 if (tableMaybe.isPresent()) {
472 final Tables table = tableMaybe.get();
473 if (table.getRoutes() instanceof Ipv4RoutesCase) {
474 final Ipv4RoutesCase routesCase = (Ipv4RoutesCase) table.getRoutes();
475 if (routesCase.getIpv4Routes() != null && routesCase.getIpv4Routes().getIpv4Route() != null) {
476 return routesCase.getIpv4Routes().getIpv4Route().size();
478 } else if (table.getRoutes() instanceof Ipv6RoutesCase) {
479 final Ipv6RoutesCase routesCase = (Ipv6RoutesCase) table.getRoutes();
480 if (routesCase.getIpv6Routes() != null && routesCase.getIpv6Routes().getIpv6Route() != null) {
481 return routesCase.getIpv6Routes().getIpv6Route().size();
485 } catch (final ReadFailedException e) {
492 public YangInstanceIdentifier getYangRibId() {
493 return this.yangRibId;
497 public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
498 return this.domDataBroker.createTransactionChain(listener);
502 public RIBExtensionConsumerContext getRibExtensions() {
503 return this.extensions;
507 public RIBSupportContextRegistry getRibSupportContext() {
508 return this.ribContextRegistry;
512 public void onGlobalContextUpdated(final SchemaContext context) {
513 this.ribContextRegistry.onSchemaContextUpdated(context);