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(), domChain, getYangRibId(), localAs, (DOMDataTreeChangeService) service, pd);
238 synchronized void initTables(final byte[] remoteBgpId) {
242 public synchronized void updateTables(final Peer peer, final Update message) {
243 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
245 if (!EOR.equals(message)) {
246 final WithdrawnRoutes wr = message.getWithdrawnRoutes();
248 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
251 * create MPUnreach for the routes to be handled in the same way as linkstate routes
253 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
254 for (final Ipv4Prefix p : wr.getWithdrawnRoutes()) {
255 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
260 new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).setWithdrawnRoutes(
261 new WithdrawnRoutesBuilder().setDestinationType(
262 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(
263 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build()).build());
265 LOG.debug("Not removing objects from unhandled IPv4 Unicast");
269 final PathAttributes attrs = message.getPathAttributes();
271 final PathAttributes2 mpu = attrs.getAugmentation(PathAttributes2.class);
273 final MpUnreachNlri nlri = mpu.getMpUnreachNlri();
274 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
275 // EOR messages do not contain withdrawn routes
276 if (nlri.getWithdrawnRoutes() != null) {
278 ari.removeRoutes(trans, peer, nlri);
280 LOG.debug("Not removing objects from unhandled NLRI {}", nlri);
283 ari.markUptodate(trans, peer);
288 final Nlri ar = message.getNlri();
290 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
293 * create MPReach for the routes to be handled in the same way as linkstate routes
295 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
296 for (final Ipv4Prefix p : ar.getNlri()) {
297 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
299 final MpReachNlriBuilder b = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(
300 UnicastSubsequentAddressFamily.class).setAdvertizedRoutes(
301 new AdvertizedRoutesBuilder().setDestinationType(
302 new DestinationIpv4CaseBuilder().setDestinationIpv4(
303 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build());
305 b.setCNextHop(attrs.getCNextHop());
308 ari.addRoutes(trans, peer, b.build(), attrs);
310 LOG.debug("Not adding objects from unhandled IPv4 Unicast");
315 final PathAttributes1 mpr = attrs.getAugmentation(PathAttributes1.class);
317 final MpReachNlri nlri = mpr.getMpReachNlri();
319 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
321 if (message.equals(ari.endOfRib())) {
322 ari.markUptodate(trans, peer);
324 ari.addRoutes(trans, peer, nlri, attrs);
327 LOG.debug("Not adding objects from unhandled NLRI {}", nlri);
332 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
334 ari.markUptodate(trans, peer);
336 LOG.debug("End-of-RIB for IPv4 Unicast ignored");
340 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
342 public void onSuccess(final Void result) {
343 LOG.debug("RIB modification successfully committed.");
347 public void onFailure(final Throwable t) {
348 LOG.error("Failed to commit RIB modification", t);
354 public synchronized void clearTable(final Peer peer, final TablesKey key) {
355 final AdjRIBsIn<?, ?> ari = this.tables.get(key);
357 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
358 ari.clear(trans, peer);
360 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
362 public void onSuccess(final Void result) {
363 LOG.trace("Table {} cleared successfully", key);
367 public void onFailure(final Throwable t) {
368 LOG.error("Failed to clear table {}", key, t);
375 public String toString() {
376 return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
379 protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
380 return toStringHelper;
383 @SuppressWarnings("unchecked")
384 protected <K, V extends Route> AdjRIBsIn<K, V> getTable(final TablesKey key) {
385 return (AdjRIBsIn<K, V>) this.tables.get(key);
389 public synchronized void close() throws InterruptedException, ExecutionException {
390 final WriteTransaction t = this.chain.newWriteOnlyTransaction();
391 t.delete(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier());
397 public AsNumber getLocalAs() {
402 public Ipv4Address getBgpIdentifier() {
403 return this.bgpIdentifier;
407 public Set<? extends BgpTableType> getLocalTables() {
408 return this.localTables;
412 public ReconnectStrategyFactory getTcpStrategyFactory() {
413 return this.tcpStrategyFactory;
417 public ReconnectStrategyFactory getSessionStrategyFactory() {
418 return this.sessionStrategyFactory;
422 public BGPDispatcher getDispatcher() {
423 return this.dispatcher;
427 public void initTable(final Peer bgpPeer, final TablesKey key) {
428 // FIXME: BUG-196: support graceful restart
432 public AdjRIBsOutRegistration registerRIBsOut(final Peer peer, final AdjRIBsOut aro) {
433 final AdjRIBsOutRegistration reg = new AdjRIBsOutRegistration(aro) {
435 protected void removeRegistration() {
436 RIBImpl.this.ribOuts.remove(peer, aro);
440 this.ribOuts.put(peer, aro);
441 LOG.debug("Registering this peer {} to RIB-Out {}", peer, this.ribOuts);
443 this.peers.put(peer);
444 new Thread(this.scheduler).start();
445 } catch (final InterruptedException e) {
452 public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction, final Throwable cause) {
453 LOG.error("Broken chain in RIB {} transaction {}", getInstanceIdentifier(), transaction.getIdentifier(), cause);
457 public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
458 LOG.info("RIB {} closed successfully", getInstanceIdentifier());
462 public long getRoutesCount(final TablesKey key) {
464 final Optional<Tables> tableMaybe = this.dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL,
465 getInstanceIdentifier().child(LocRib.class).child(Tables.class, key)).checkedGet();
466 if (tableMaybe.isPresent()) {
467 final Tables table = tableMaybe.get();
468 if (table.getRoutes() instanceof Ipv4RoutesCase) {
469 final Ipv4RoutesCase routesCase = (Ipv4RoutesCase) table.getRoutes();
470 if (routesCase.getIpv4Routes() != null && routesCase.getIpv4Routes().getIpv4Route() != null) {
471 return routesCase.getIpv4Routes().getIpv4Route().size();
473 } else if (table.getRoutes() instanceof Ipv6RoutesCase) {
474 final Ipv6RoutesCase routesCase = (Ipv6RoutesCase) table.getRoutes();
475 if (routesCase.getIpv6Routes() != null && routesCase.getIpv6Routes().getIpv6Route() != null) {
476 return routesCase.getIpv6Routes().getIpv6Route().size();
480 } catch (final ReadFailedException e) {
487 public YangInstanceIdentifier getYangRibId() {
488 return this.yangRibId;
492 public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
493 return this.domDataBroker.createTransactionChain(listener);
497 public RIBExtensionConsumerContext getRibExtensions() {
498 return this.extensions;
502 public RIBSupportContextRegistry getRibSupportContext() {
503 return this.ribContextRegistry;
507 public void onGlobalContextUpdated(final SchemaContext context) {
508 this.ribContextRegistry.onSchemaContextUpdated(context);