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;
142 private final DOMDataBrokerExtension service;
144 private final Runnable scheduler = new Runnable() {
148 final Peer peer = RIBImpl.this.peers.take();
149 LOG.debug("Advertizing loc-rib to new peer {}.", peer);
150 for (final BgpTableType key : RIBImpl.this.localTables) {
152 synchronized (RIBImpl.this) {
153 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(RIBImpl.this.ribOuts, RIBImpl.this.comparator, RIBImpl.this.chain.newWriteOnlyTransaction());
154 final AbstractAdjRIBs<?, ?, ?> adj = (AbstractAdjRIBs<?, ?, ?>) RIBImpl.this.tables.get(new TablesKey(key.getAfi(), key.getSafi()));
155 adj.addAllEntries(trans);
156 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
158 public void onSuccess(final Void result) {
159 LOG.trace("Advertizing {} to peer {} committed successfully", key.getAfi(), peer);
162 public void onFailure(final Throwable t) {
163 LOG.error("Failed to update peer {} with RIB {}", peer, t);
168 } catch (final InterruptedException e) {
169 LOG.info("Scheduler thread was interrupted.", e);
174 public RIBImpl(final RibId ribId, final AsNumber localAs, final Ipv4Address localBgpId, final Ipv4Address clusterId, final RIBExtensionConsumerContext extensions,
175 final BGPDispatcher dispatcher, final ReconnectStrategyFactory tcpStrategyFactory, final BindingCodecTreeFactory codecFactory,
176 final ReconnectStrategyFactory sessionStrategyFactory, final DataBroker dps, final DOMDataBroker domDataBroker, final List<BgpTableType> localTables, final GeneratedClassLoadingStrategy classStrategy) {
177 super(InstanceIdentifier.create(BgpRib.class).child(Rib.class, new RibKey(Preconditions.checkNotNull(ribId))));
178 this.chain = dps.createTransactionChain(this);
179 this.localAs = Preconditions.checkNotNull(localAs);
180 this.comparator = new BGPObjectComparator(localAs);
181 this.bgpIdentifier = Preconditions.checkNotNull(localBgpId);
182 this.clusterId = (clusterId == null) ? new ClusterIdentifier(localBgpId) : new ClusterIdentifier(clusterId);
183 this.dispatcher = Preconditions.checkNotNull(dispatcher);
184 this.sessionStrategyFactory = Preconditions.checkNotNull(sessionStrategyFactory);
185 this.tcpStrategyFactory = Preconditions.checkNotNull(tcpStrategyFactory);
186 this.localTables = ImmutableSet.copyOf(localTables);
187 this.localTablesKeys = new HashSet<TablesKey>();
188 this.tables = new RIBTables(extensions);
189 this.peers = new LinkedBlockingQueue<>();
190 this.dataBroker = dps;
191 this.domDataBroker = Preconditions.checkNotNull(domDataBroker);
192 this.extensions = Preconditions.checkNotNull(extensions);
193 this.ribContextRegistry = RIBSupportContextRegistryImpl.create(extensions, codecFactory, classStrategy);
194 this.yangRibId = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Rib.QNAME).nodeWithKey(Rib.QNAME, RIB_ID_QNAME, ribId.getValue()).build();
196 LOG.debug("Instantiating RIB table {} at {}", ribId, getInstanceIdentifier());
198 final WriteTransaction trans = this.chain.newWriteOnlyTransaction();
200 // put empty BgpRib if not exists
201 trans.put(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier(),
202 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(
203 new LocRibBuilder().setTables(Collections.<Tables> emptyList()).build()).build(), true);
205 for (final BgpTableType t : localTables) {
206 final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
207 this.localTablesKeys.add(key);
208 if (this.tables.create(trans, this, key) == null) {
209 LOG.debug("Did not create local table for unhandled table type {}", t);
213 Futures.addCallback(trans.submit(), new FutureCallback<Void>() {
215 public void onSuccess(final Void result) {
216 LOG.trace("Change committed successfully");
220 public void onFailure(final Throwable t) {
221 LOG.error("Failed to initiate RIB {}", getInstanceIdentifier(), t);
226 final PolicyDatabase pd = new PolicyDatabase(localAs.getValue(), localBgpId, this.clusterId);
228 final DOMDataBrokerExtension service = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
229 this.service = service;
230 this.efWriter = EffectiveRibInWriter.create(getService(), this.createPeerChain(this), getYangRibId(), pd, this.ribContextRegistry);
231 LOG.debug("Effective RIB created.");
233 for (final BgpTableType t : localTables) {
234 final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
235 // create locRibWriter for each table
236 LocRibWriter.create(this.ribContextRegistry, key, this.createPeerChain(this), getYangRibId(), localAs, getService(), pd);
241 synchronized void initTables(final byte[] remoteBgpId) {
246 public synchronized void updateTables(final Peer peer, final Update message) {
247 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
249 if (!EOR.equals(message)) {
250 final WithdrawnRoutes wr = message.getWithdrawnRoutes();
252 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
255 * create MPUnreach for the routes to be handled in the same way as linkstate routes
257 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
258 for (final Ipv4Prefix p : wr.getWithdrawnRoutes()) {
259 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
264 new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).setWithdrawnRoutes(
265 new WithdrawnRoutesBuilder().setDestinationType(
266 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(
267 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build()).build());
269 LOG.debug("Not removing objects from unhandled IPv4 Unicast");
273 final Attributes attrs = message.getAttributes();
275 final Attributes2 mpu = attrs.getAugmentation(Attributes2.class);
277 final MpUnreachNlri nlri = mpu.getMpUnreachNlri();
278 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
279 // EOR messages do not contain withdrawn routes
280 if (nlri.getWithdrawnRoutes() != null) {
282 ari.removeRoutes(trans, peer, nlri);
284 LOG.debug("Not removing objects from unhandled NLRI {}", nlri);
287 ari.markUptodate(trans, peer);
292 final Nlri ar = message.getNlri();
294 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
297 * create MPReach for the routes to be handled in the same way as linkstate routes
299 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
300 for (final Ipv4Prefix p : ar.getNlri()) {
301 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
303 final MpReachNlriBuilder b = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(
304 UnicastSubsequentAddressFamily.class).setAdvertizedRoutes(
305 new AdvertizedRoutesBuilder().setDestinationType(
306 new DestinationIpv4CaseBuilder().setDestinationIpv4(
307 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build());
309 b.setCNextHop(attrs.getCNextHop());
312 ari.addRoutes(trans, peer, b.build(), attrs);
314 LOG.debug("Not adding objects from unhandled IPv4 Unicast");
319 final Attributes1 mpr = attrs.getAugmentation(Attributes1.class);
321 final MpReachNlri nlri = mpr.getMpReachNlri();
323 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
325 if (message.equals(ari.endOfRib())) {
326 ari.markUptodate(trans, peer);
328 ari.addRoutes(trans, peer, nlri, attrs);
331 LOG.debug("Not adding objects from unhandled NLRI {}", nlri);
336 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
338 ari.markUptodate(trans, peer);
340 LOG.debug("End-of-RIB for IPv4 Unicast ignored");
344 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
346 public void onSuccess(final Void result) {
347 LOG.debug("RIB modification successfully committed.");
351 public void onFailure(final Throwable t) {
352 LOG.error("Failed to commit RIB modification", t);
359 public synchronized void clearTable(final Peer peer, final TablesKey key) {
360 final AdjRIBsIn<?, ?> ari = this.tables.get(key);
362 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
363 ari.clear(trans, peer);
365 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
367 public void onSuccess(final Void result) {
368 LOG.trace("Table {} cleared successfully", key);
372 public void onFailure(final Throwable t) {
373 LOG.error("Failed to clear table {}", key, t);
380 public String toString() {
381 return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
384 protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
385 return toStringHelper;
388 @SuppressWarnings("unchecked")
390 protected <K, V extends Route> AdjRIBsIn<K, V> getTable(final TablesKey key) {
391 return (AdjRIBsIn<K, V>) this.tables.get(key);
395 public synchronized void close() throws InterruptedException, ExecutionException {
396 final WriteTransaction t = this.chain.newWriteOnlyTransaction();
397 t.delete(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier());
403 public AsNumber getLocalAs() {
408 public Ipv4Address getBgpIdentifier() {
409 return this.bgpIdentifier;
413 public Set<? extends BgpTableType> getLocalTables() {
414 return this.localTables;
418 public ReconnectStrategyFactory getTcpStrategyFactory() {
419 return this.tcpStrategyFactory;
423 public ReconnectStrategyFactory getSessionStrategyFactory() {
424 return this.sessionStrategyFactory;
428 public BGPDispatcher getDispatcher() {
429 return this.dispatcher;
434 public void initTable(final Peer bgpPeer, final TablesKey key) {
435 // FIXME: BUG-196: support graceful restart
439 public AdjRIBsOutRegistration registerRIBsOut(final Peer peer, final AdjRIBsOut aro) {
440 final AdjRIBsOutRegistration reg = new AdjRIBsOutRegistration(aro) {
442 protected void removeRegistration() {
443 RIBImpl.this.ribOuts.remove(peer, aro);
447 this.ribOuts.put(peer, aro);
448 LOG.debug("Registering this peer {} to RIB-Out {}", peer, this.ribOuts);
450 this.peers.put(peer);
451 new Thread(this.scheduler).start();
452 } catch (final InterruptedException e) {
459 public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction, final Throwable cause) {
460 LOG.error("Broken chain in RIB {} transaction {}", getInstanceIdentifier(), transaction.getIdentifier(), cause);
464 public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
465 LOG.info("RIB {} closed successfully", getInstanceIdentifier());
469 public long getRoutesCount(final TablesKey key) {
471 final Optional<Tables> tableMaybe = this.dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL,
472 getInstanceIdentifier().child(LocRib.class).child(Tables.class, key)).checkedGet();
473 if (tableMaybe.isPresent()) {
474 final Tables table = tableMaybe.get();
475 if (table.getRoutes() instanceof Ipv4RoutesCase) {
476 final Ipv4RoutesCase routesCase = (Ipv4RoutesCase) table.getRoutes();
477 if (routesCase.getIpv4Routes() != null && routesCase.getIpv4Routes().getIpv4Route() != null) {
478 return routesCase.getIpv4Routes().getIpv4Route().size();
480 } else if (table.getRoutes() instanceof Ipv6RoutesCase) {
481 final Ipv6RoutesCase routesCase = (Ipv6RoutesCase) table.getRoutes();
482 if (routesCase.getIpv6Routes() != null && routesCase.getIpv6Routes().getIpv6Route() != null) {
483 return routesCase.getIpv6Routes().getIpv6Route().size();
487 } catch (final ReadFailedException e) {
493 public Set<TablesKey> getLocalTablesKeys() {
494 return this.localTablesKeys;
497 public DOMDataTreeChangeService getService() {
498 return (DOMDataTreeChangeService) this.service;
502 public YangInstanceIdentifier getYangRibId() {
503 return this.yangRibId;
507 public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
508 return this.domDataBroker.createTransactionChain(listener);
512 public RIBExtensionConsumerContext getRibExtensions() {
513 return this.extensions;
517 public RIBSupportContextRegistry getRibSupportContext() {
518 return this.ribContextRegistry;
522 public void onGlobalContextUpdated(final SchemaContext context) {
523 this.ribContextRegistry.onSchemaContextUpdated(context);