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 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, final 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) ? new ClusterIdentifier(localBgpId) : new ClusterIdentifier(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, this.clusterId);
196 final DOMDataBrokerExtension service = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
197 final DOMTransactionChain domChain = this.createPeerChain(this);
198 EffectiveRibInWriter.create((DOMDataTreeChangeService) service, domChain, getYangRibId(), pd, this.ribContextRegistry);
199 LOG.debug("Effective RIB created.");
201 // put empty BgpRib if not exists
202 trans.put(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier(),
203 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(
204 new LocRibBuilder().setTables(Collections.<Tables> emptyList()).build()).build(), true);
206 for (final BgpTableType t : localTables) {
207 final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
208 if (this.tables.create(trans, this, key) == null) {
209 LOG.debug("Did not create local table for unhandled table type {}", t);
212 // reusing the for cycle
213 // create locRibWriter for each table
214 // FIXME: temporary create writer only for Ipv4
215 if (key.getAfi().equals(Ipv4AddressFamily.class)) {
216 LocRibWriter.create(this.ribContextRegistry.getRIBSupportContext(key).getRibSupport(), domChain, getYangRibId(), localAs, (DOMDataTreeChangeService) service, pd);
220 Futures.addCallback(trans.submit(), new FutureCallback<Void>() {
222 public void onSuccess(final Void result) {
223 LOG.trace("Change committed successfully");
227 public void onFailure(final Throwable t) {
228 LOG.error("Failed to initiate RIB {}", getInstanceIdentifier(), t);
234 synchronized void initTables(final byte[] remoteBgpId) {
238 public synchronized void updateTables(final Peer peer, final Update message) {
239 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
241 if (!EOR.equals(message)) {
242 final WithdrawnRoutes wr = message.getWithdrawnRoutes();
244 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
247 * create MPUnreach for the routes to be handled in the same way as linkstate routes
249 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
250 for (final Ipv4Prefix p : wr.getWithdrawnRoutes()) {
251 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
256 new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).setWithdrawnRoutes(
257 new WithdrawnRoutesBuilder().setDestinationType(
258 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(
259 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build()).build());
261 LOG.debug("Not removing objects from unhandled IPv4 Unicast");
265 final PathAttributes attrs = message.getPathAttributes();
267 final PathAttributes2 mpu = attrs.getAugmentation(PathAttributes2.class);
269 final MpUnreachNlri nlri = mpu.getMpUnreachNlri();
270 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
271 // EOR messages do not contain withdrawn routes
272 if (nlri.getWithdrawnRoutes() != null) {
274 ari.removeRoutes(trans, peer, nlri);
276 LOG.debug("Not removing objects from unhandled NLRI {}", nlri);
279 ari.markUptodate(trans, peer);
284 final Nlri ar = message.getNlri();
286 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
289 * create MPReach for the routes to be handled in the same way as linkstate routes
291 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
292 for (final Ipv4Prefix p : ar.getNlri()) {
293 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
295 final MpReachNlriBuilder b = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(
296 UnicastSubsequentAddressFamily.class).setAdvertizedRoutes(
297 new AdvertizedRoutesBuilder().setDestinationType(
298 new DestinationIpv4CaseBuilder().setDestinationIpv4(
299 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build());
301 b.setCNextHop(attrs.getCNextHop());
304 ari.addRoutes(trans, peer, b.build(), attrs);
306 LOG.debug("Not adding objects from unhandled IPv4 Unicast");
311 final PathAttributes1 mpr = attrs.getAugmentation(PathAttributes1.class);
313 final MpReachNlri nlri = mpr.getMpReachNlri();
315 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
317 if (message.equals(ari.endOfRib())) {
318 ari.markUptodate(trans, peer);
320 ari.addRoutes(trans, peer, nlri, attrs);
323 LOG.debug("Not adding objects from unhandled NLRI {}", nlri);
328 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
330 ari.markUptodate(trans, peer);
332 LOG.debug("End-of-RIB for IPv4 Unicast ignored");
336 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
338 public void onSuccess(final Void result) {
339 LOG.debug("RIB modification successfully committed.");
343 public void onFailure(final Throwable t) {
344 LOG.error("Failed to commit RIB modification", t);
350 public synchronized void clearTable(final Peer peer, final TablesKey key) {
351 final AdjRIBsIn<?, ?> ari = this.tables.get(key);
353 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
354 ari.clear(trans, peer);
356 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
358 public void onSuccess(final Void result) {
359 LOG.trace("Table {} cleared successfully", key);
363 public void onFailure(final Throwable t) {
364 LOG.error("Failed to clear table {}", key, t);
371 public String toString() {
372 return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
375 protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
376 return toStringHelper;
379 @SuppressWarnings("unchecked")
380 protected <K, V extends Route> AdjRIBsIn<K, V> getTable(final TablesKey key) {
381 return (AdjRIBsIn<K, V>) this.tables.get(key);
385 public synchronized void close() throws InterruptedException, ExecutionException {
386 final WriteTransaction t = this.chain.newWriteOnlyTransaction();
387 t.delete(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier());
393 public AsNumber getLocalAs() {
398 public Ipv4Address getBgpIdentifier() {
399 return this.bgpIdentifier;
403 public Set<? extends BgpTableType> getLocalTables() {
404 return this.localTables;
408 public ReconnectStrategyFactory getTcpStrategyFactory() {
409 return this.tcpStrategyFactory;
413 public ReconnectStrategyFactory getSessionStrategyFactory() {
414 return this.sessionStrategyFactory;
418 public BGPDispatcher getDispatcher() {
419 return this.dispatcher;
423 public void initTable(final Peer bgpPeer, final TablesKey key) {
424 // FIXME: BUG-196: support graceful restart
428 public AdjRIBsOutRegistration registerRIBsOut(final Peer peer, final AdjRIBsOut aro) {
429 final AdjRIBsOutRegistration reg = new AdjRIBsOutRegistration(aro) {
431 protected void removeRegistration() {
432 RIBImpl.this.ribOuts.remove(peer, aro);
436 this.ribOuts.put(peer, aro);
437 LOG.debug("Registering this peer {} to RIB-Out {}", peer, this.ribOuts);
439 this.peers.put(peer);
440 new Thread(this.scheduler).start();
441 } catch (final InterruptedException e) {
448 public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction, final Throwable cause) {
449 LOG.error("Broken chain in RIB {} transaction {}", getInstanceIdentifier(), transaction.getIdentifier(), cause);
453 public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
454 LOG.info("RIB {} closed successfully", getInstanceIdentifier());
458 public long getRoutesCount(final TablesKey key) {
460 final Optional<Tables> tableMaybe = this.dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL,
461 getInstanceIdentifier().child(LocRib.class).child(Tables.class, key)).checkedGet();
462 if (tableMaybe.isPresent()) {
463 final Tables table = tableMaybe.get();
464 if (table.getRoutes() instanceof Ipv4RoutesCase) {
465 final Ipv4RoutesCase routesCase = (Ipv4RoutesCase) table.getRoutes();
466 if (routesCase.getIpv4Routes() != null && routesCase.getIpv4Routes().getIpv4Route() != null) {
467 return routesCase.getIpv4Routes().getIpv4Route().size();
469 } else if (table.getRoutes() instanceof Ipv6RoutesCase) {
470 final Ipv6RoutesCase routesCase = (Ipv6RoutesCase) table.getRoutes();
471 if (routesCase.getIpv6Routes() != null && routesCase.getIpv6Routes().getIpv6Route() != null) {
472 return routesCase.getIpv6Routes().getIpv6Route().size();
476 } catch (final ReadFailedException e) {
483 public YangInstanceIdentifier getYangRibId() {
484 return this.yangRibId;
488 public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
489 return this.domDataBroker.createTransactionChain(listener);
493 public RIBExtensionConsumerContext getRibExtensions() {
494 return this.extensions;
498 public RIBSupportContextRegistry getRibSupportContext() {
499 return this.ribContextRegistry;
503 public void onGlobalContextUpdated(final SchemaContext context) {
504 this.ribContextRegistry.onSchemaContextUpdated(context);