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);
235 synchronized void initTables(final byte[] remoteBgpId) {
240 public synchronized void updateTables(final Peer peer, final Update message) {
241 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
243 if (!EOR.equals(message)) {
244 final WithdrawnRoutes wr = message.getWithdrawnRoutes();
246 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
249 * create MPUnreach for the routes to be handled in the same way as linkstate routes
251 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
252 for (final Ipv4Prefix p : wr.getWithdrawnRoutes()) {
253 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
258 new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).setWithdrawnRoutes(
259 new WithdrawnRoutesBuilder().setDestinationType(
260 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(
261 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build()).build());
263 LOG.debug("Not removing objects from unhandled IPv4 Unicast");
267 final PathAttributes attrs = message.getPathAttributes();
269 final PathAttributes2 mpu = attrs.getAugmentation(PathAttributes2.class);
271 final MpUnreachNlri nlri = mpu.getMpUnreachNlri();
272 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
273 // EOR messages do not contain withdrawn routes
274 if (nlri.getWithdrawnRoutes() != null) {
276 ari.removeRoutes(trans, peer, nlri);
278 LOG.debug("Not removing objects from unhandled NLRI {}", nlri);
281 ari.markUptodate(trans, peer);
286 final Nlri ar = message.getNlri();
288 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
291 * create MPReach for the routes to be handled in the same way as linkstate routes
293 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
294 for (final Ipv4Prefix p : ar.getNlri()) {
295 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
297 final MpReachNlriBuilder b = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(
298 UnicastSubsequentAddressFamily.class).setAdvertizedRoutes(
299 new AdvertizedRoutesBuilder().setDestinationType(
300 new DestinationIpv4CaseBuilder().setDestinationIpv4(
301 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build());
303 b.setCNextHop(attrs.getCNextHop());
306 ari.addRoutes(trans, peer, b.build(), attrs);
308 LOG.debug("Not adding objects from unhandled IPv4 Unicast");
313 final PathAttributes1 mpr = attrs.getAugmentation(PathAttributes1.class);
315 final MpReachNlri nlri = mpr.getMpReachNlri();
317 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
319 if (message.equals(ari.endOfRib())) {
320 ari.markUptodate(trans, peer);
322 ari.addRoutes(trans, peer, nlri, attrs);
325 LOG.debug("Not adding objects from unhandled NLRI {}", nlri);
330 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
332 ari.markUptodate(trans, peer);
334 LOG.debug("End-of-RIB for IPv4 Unicast ignored");
338 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
340 public void onSuccess(final Void result) {
341 LOG.debug("RIB modification successfully committed.");
345 public void onFailure(final Throwable t) {
346 LOG.error("Failed to commit RIB modification", t);
353 public synchronized void clearTable(final Peer peer, final TablesKey key) {
354 final AdjRIBsIn<?, ?> ari = this.tables.get(key);
356 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
357 ari.clear(trans, peer);
359 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
361 public void onSuccess(final Void result) {
362 LOG.trace("Table {} cleared successfully", key);
366 public void onFailure(final Throwable t) {
367 LOG.error("Failed to clear table {}", key, t);
374 public String toString() {
375 return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
378 protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
379 return toStringHelper;
382 @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;
428 public void initTable(final Peer bgpPeer, final TablesKey key) {
429 // FIXME: BUG-196: support graceful restart
433 public AdjRIBsOutRegistration registerRIBsOut(final Peer peer, final AdjRIBsOut aro) {
434 final AdjRIBsOutRegistration reg = new AdjRIBsOutRegistration(aro) {
436 protected void removeRegistration() {
437 RIBImpl.this.ribOuts.remove(peer, aro);
441 this.ribOuts.put(peer, aro);
442 LOG.debug("Registering this peer {} to RIB-Out {}", peer, this.ribOuts);
444 this.peers.put(peer);
445 new Thread(this.scheduler).start();
446 } catch (final InterruptedException e) {
453 public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction, final Throwable cause) {
454 LOG.error("Broken chain in RIB {} transaction {}", getInstanceIdentifier(), transaction.getIdentifier(), cause);
458 public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
459 LOG.info("RIB {} closed successfully", getInstanceIdentifier());
463 public long getRoutesCount(final TablesKey key) {
465 final Optional<Tables> tableMaybe = this.dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL,
466 getInstanceIdentifier().child(LocRib.class).child(Tables.class, key)).checkedGet();
467 if (tableMaybe.isPresent()) {
468 final Tables table = tableMaybe.get();
469 if (table.getRoutes() instanceof Ipv4RoutesCase) {
470 final Ipv4RoutesCase routesCase = (Ipv4RoutesCase) table.getRoutes();
471 if (routesCase.getIpv4Routes() != null && routesCase.getIpv4Routes().getIpv4Route() != null) {
472 return routesCase.getIpv4Routes().getIpv4Route().size();
474 } else if (table.getRoutes() instanceof Ipv6RoutesCase) {
475 final Ipv6RoutesCase routesCase = (Ipv6RoutesCase) table.getRoutes();
476 if (routesCase.getIpv6Routes() != null && routesCase.getIpv6Routes().getIpv6Route() != null) {
477 return routesCase.getIpv6Routes().getIpv6Route().size();
481 } catch (final ReadFailedException e) {
488 public YangInstanceIdentifier getYangRibId() {
489 return this.yangRibId;
493 public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
494 return this.domDataBroker.createTransactionChain(listener);
498 public RIBExtensionConsumerContext getRibExtensions() {
499 return this.extensions;
503 public RIBSupportContextRegistry getRibSupportContext() {
504 return this.ribContextRegistry;
508 public void onGlobalContextUpdated(final SchemaContext context) {
509 this.ribContextRegistry.onSchemaContextUpdated(context);