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.HashSet;
20 import java.util.List;
22 import java.util.concurrent.BlockingQueue;
23 import java.util.concurrent.ConcurrentHashMap;
24 import java.util.concurrent.ConcurrentMap;
25 import java.util.concurrent.ExecutionException;
26 import java.util.concurrent.LinkedBlockingQueue;
27 import javax.annotation.concurrent.ThreadSafe;
28 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
29 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
30 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
31 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
32 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
33 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
34 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
35 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
36 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
37 import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
38 import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
39 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
40 import org.opendaylight.protocol.bgp.rib.DefaultRibReference;
41 import org.opendaylight.protocol.bgp.rib.impl.spi.AdjRIBsOut;
42 import org.opendaylight.protocol.bgp.rib.impl.spi.AdjRIBsOutRegistration;
43 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
44 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
45 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
46 import org.opendaylight.protocol.bgp.rib.spi.AbstractAdjRIBs;
47 import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsIn;
48 import org.opendaylight.protocol.bgp.rib.spi.BGPObjectComparator;
49 import org.opendaylight.protocol.bgp.rib.spi.Peer;
50 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
51 import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.bgp.rib.rib.loc.rib.tables.routes.Ipv4RoutesCase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.bgp.rib.rib.loc.rib.tables.routes.Ipv6RoutesCase;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.DestinationIpv4Builder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.destination.ipv4.Ipv4Prefixes;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.destination.ipv4.Ipv4PrefixesBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationIpv4CaseBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.UpdateBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.Nlri;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.WithdrawnRoutes;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibKey;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRib;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRibBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
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 Set<TablesKey> localTablesKeys;
134 private final RIBTables tables;
135 private final BlockingQueue<Peer> peers;
136 private final DataBroker dataBroker;
137 private final DOMDataBroker domDataBroker;
138 private final RIBExtensionConsumerContext extensions;
139 private final YangInstanceIdentifier yangRibId;
140 private final RIBSupportContextRegistryImpl ribContextRegistry;
141 private final EffectiveRibInWriter efWriter;
143 private final Runnable scheduler = new Runnable() {
147 final Peer peer = RIBImpl.this.peers.take();
148 LOG.debug("Advertizing loc-rib to new peer {}.", peer);
149 for (final BgpTableType key : RIBImpl.this.localTables) {
151 synchronized (RIBImpl.this) {
152 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(RIBImpl.this.ribOuts, RIBImpl.this.comparator, RIBImpl.this.chain.newWriteOnlyTransaction());
153 final AbstractAdjRIBs<?, ?, ?> adj = (AbstractAdjRIBs<?, ?, ?>) RIBImpl.this.tables.get(new TablesKey(key.getAfi(), key.getSafi()));
154 adj.addAllEntries(trans);
155 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
157 public void onSuccess(final Void result) {
158 LOG.trace("Advertizing {} to peer {} committed successfully", key.getAfi(), peer);
161 public void onFailure(final Throwable t) {
162 LOG.error("Failed to update peer {} with RIB {}", peer, t);
167 } catch (final InterruptedException e) {
168 LOG.info("Scheduler thread was interrupted.", e);
173 public RIBImpl(final RibId ribId, final AsNumber localAs, final Ipv4Address localBgpId, final Ipv4Address clusterId, final RIBExtensionConsumerContext extensions,
174 final BGPDispatcher dispatcher, final ReconnectStrategyFactory tcpStrategyFactory, final BindingCodecTreeFactory codecFactory,
175 final ReconnectStrategyFactory sessionStrategyFactory, final DataBroker dps, final DOMDataBroker domDataBroker, final List<BgpTableType> localTables, final GeneratedClassLoadingStrategy classStrategy) {
176 super(InstanceIdentifier.create(BgpRib.class).child(Rib.class, new RibKey(Preconditions.checkNotNull(ribId))));
177 this.chain = dps.createTransactionChain(this);
178 this.localAs = Preconditions.checkNotNull(localAs);
179 this.comparator = new BGPObjectComparator(localAs);
180 this.bgpIdentifier = Preconditions.checkNotNull(localBgpId);
181 this.clusterId = (clusterId == null) ? new ClusterIdentifier(localBgpId) : new ClusterIdentifier(clusterId);
182 this.dispatcher = Preconditions.checkNotNull(dispatcher);
183 this.sessionStrategyFactory = Preconditions.checkNotNull(sessionStrategyFactory);
184 this.tcpStrategyFactory = Preconditions.checkNotNull(tcpStrategyFactory);
185 this.localTables = ImmutableSet.copyOf(localTables);
186 this.localTablesKeys = new HashSet<TablesKey>();
187 this.tables = new RIBTables(extensions);
188 this.peers = new LinkedBlockingQueue<>();
189 this.dataBroker = dps;
190 this.domDataBroker = Preconditions.checkNotNull(domDataBroker);
191 this.extensions = Preconditions.checkNotNull(extensions);
192 this.ribContextRegistry = RIBSupportContextRegistryImpl.create(extensions, codecFactory, classStrategy);
193 this.yangRibId = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Rib.QNAME).nodeWithKey(Rib.QNAME, RIB_ID_QNAME, ribId.getValue()).build();
195 LOG.debug("Instantiating RIB table {} at {}", ribId, getInstanceIdentifier());
197 final WriteTransaction trans = this.chain.newWriteOnlyTransaction();
199 // put empty BgpRib if not exists
200 trans.put(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier(),
201 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(
202 new LocRibBuilder().setTables(Collections.<Tables> emptyList()).build()).build(), true);
204 for (final BgpTableType t : localTables) {
205 final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
206 this.localTablesKeys.add(key);
207 if (this.tables.create(trans, this, key) == null) {
208 LOG.debug("Did not create local table for unhandled table type {}", t);
212 Futures.addCallback(trans.submit(), new FutureCallback<Void>() {
214 public void onSuccess(final Void result) {
215 LOG.trace("Change committed successfully");
219 public void onFailure(final Throwable t) {
220 LOG.error("Failed to initiate RIB {}", getInstanceIdentifier(), t);
225 final PolicyDatabase pd = new PolicyDatabase(localAs.getValue(), localBgpId, this.clusterId);
227 final DOMDataBrokerExtension service = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
228 final DOMTransactionChain domChain = this.createPeerChain(this);
229 this.efWriter = EffectiveRibInWriter.create((DOMDataTreeChangeService) service, this.createPeerChain(this), getYangRibId(), pd, this.ribContextRegistry);
230 LOG.debug("Effective RIB created.");
232 for (final BgpTableType t : localTables) {
233 final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
234 // create locRibWriter for each table
235 LocRibWriter.create(this.ribContextRegistry, 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.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 Attributes attrs = message.getAttributes();
274 final Attributes2 mpu = attrs.getAugmentation(Attributes2.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 Attributes1 mpr = attrs.getAugmentation(Attributes1.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) {
492 public Set<TablesKey> getLocalTablesKeys() {
493 return this.localTablesKeys;
497 public YangInstanceIdentifier getYangRibId() {
498 return this.yangRibId;
502 public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
503 return this.domDataBroker.createTransactionChain(listener);
507 public RIBExtensionConsumerContext getRibExtensions() {
508 return this.extensions;
512 public RIBSupportContextRegistry getRibSupportContext() {
513 return this.ribContextRegistry;
517 public void onGlobalContextUpdated(final SchemaContext context) {
518 this.ribContextRegistry.onSchemaContextUpdated(context);