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.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.path.attributes.Attributes;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.Nlri;
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.Attributes1;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.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, this.createPeerChain(this), 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 LocRibWriter.create(this.ribContextRegistry, key, this.createPeerChain(this), getYangRibId(), localAs, (DOMDataTreeChangeService) service, pd);
236 synchronized void initTables(final byte[] remoteBgpId) {
241 public synchronized void updateTables(final Peer peer, final Update message) {
242 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
244 if (!EOR.equals(message)) {
245 final WithdrawnRoutes wr = message.getWithdrawnRoutes();
247 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
250 * create MPUnreach for the routes to be handled in the same way as linkstate routes
252 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
253 for (final Ipv4Prefix p : wr.getWithdrawnRoutes()) {
254 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
259 new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).setWithdrawnRoutes(
260 new WithdrawnRoutesBuilder().setDestinationType(
261 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(
262 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build()).build());
264 LOG.debug("Not removing objects from unhandled IPv4 Unicast");
268 final Attributes attrs = message.getAttributes();
270 final Attributes2 mpu = attrs.getAugmentation(Attributes2.class);
272 final MpUnreachNlri nlri = mpu.getMpUnreachNlri();
273 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
274 // EOR messages do not contain withdrawn routes
275 if (nlri.getWithdrawnRoutes() != null) {
277 ari.removeRoutes(trans, peer, nlri);
279 LOG.debug("Not removing objects from unhandled NLRI {}", nlri);
282 ari.markUptodate(trans, peer);
287 final Nlri ar = message.getNlri();
289 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
292 * create MPReach for the routes to be handled in the same way as linkstate routes
294 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
295 for (final Ipv4Prefix p : ar.getNlri()) {
296 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
298 final MpReachNlriBuilder b = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(
299 UnicastSubsequentAddressFamily.class).setAdvertizedRoutes(
300 new AdvertizedRoutesBuilder().setDestinationType(
301 new DestinationIpv4CaseBuilder().setDestinationIpv4(
302 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build());
304 b.setCNextHop(attrs.getCNextHop());
307 ari.addRoutes(trans, peer, b.build(), attrs);
309 LOG.debug("Not adding objects from unhandled IPv4 Unicast");
314 final Attributes1 mpr = attrs.getAugmentation(Attributes1.class);
316 final MpReachNlri nlri = mpr.getMpReachNlri();
318 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
320 if (message.equals(ari.endOfRib())) {
321 ari.markUptodate(trans, peer);
323 ari.addRoutes(trans, peer, nlri, attrs);
326 LOG.debug("Not adding objects from unhandled NLRI {}", nlri);
331 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
333 ari.markUptodate(trans, peer);
335 LOG.debug("End-of-RIB for IPv4 Unicast ignored");
339 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
341 public void onSuccess(final Void result) {
342 LOG.debug("RIB modification successfully committed.");
346 public void onFailure(final Throwable t) {
347 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")
385 protected <K, V extends Route> AdjRIBsIn<K, V> getTable(final TablesKey key) {
386 return (AdjRIBsIn<K, V>) this.tables.get(key);
390 public synchronized void close() throws InterruptedException, ExecutionException {
391 final WriteTransaction t = this.chain.newWriteOnlyTransaction();
392 t.delete(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier());
398 public AsNumber getLocalAs() {
403 public Ipv4Address getBgpIdentifier() {
404 return this.bgpIdentifier;
408 public Set<? extends BgpTableType> getLocalTables() {
409 return this.localTables;
413 public ReconnectStrategyFactory getTcpStrategyFactory() {
414 return this.tcpStrategyFactory;
418 public ReconnectStrategyFactory getSessionStrategyFactory() {
419 return this.sessionStrategyFactory;
423 public BGPDispatcher getDispatcher() {
424 return this.dispatcher;
429 public void initTable(final Peer bgpPeer, final TablesKey key) {
430 // FIXME: BUG-196: support graceful restart
434 public AdjRIBsOutRegistration registerRIBsOut(final Peer peer, final AdjRIBsOut aro) {
435 final AdjRIBsOutRegistration reg = new AdjRIBsOutRegistration(aro) {
437 protected void removeRegistration() {
438 RIBImpl.this.ribOuts.remove(peer, aro);
442 this.ribOuts.put(peer, aro);
443 LOG.debug("Registering this peer {} to RIB-Out {}", peer, this.ribOuts);
445 this.peers.put(peer);
446 new Thread(this.scheduler).start();
447 } catch (final InterruptedException e) {
454 public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction, final Throwable cause) {
455 LOG.error("Broken chain in RIB {} transaction {}", getInstanceIdentifier(), transaction.getIdentifier(), cause);
459 public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
460 LOG.info("RIB {} closed successfully", getInstanceIdentifier());
464 public long getRoutesCount(final TablesKey key) {
466 final Optional<Tables> tableMaybe = this.dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL,
467 getInstanceIdentifier().child(LocRib.class).child(Tables.class, key)).checkedGet();
468 if (tableMaybe.isPresent()) {
469 final Tables table = tableMaybe.get();
470 if (table.getRoutes() instanceof Ipv4RoutesCase) {
471 final Ipv4RoutesCase routesCase = (Ipv4RoutesCase) table.getRoutes();
472 if (routesCase.getIpv4Routes() != null && routesCase.getIpv4Routes().getIpv4Route() != null) {
473 return routesCase.getIpv4Routes().getIpv4Route().size();
475 } else if (table.getRoutes() instanceof Ipv6RoutesCase) {
476 final Ipv6RoutesCase routesCase = (Ipv6RoutesCase) table.getRoutes();
477 if (routesCase.getIpv6Routes() != null && routesCase.getIpv6Routes().getIpv6Route() != null) {
478 return routesCase.getIpv6Routes().getIpv6Route().size();
482 } catch (final ReadFailedException e) {
489 public YangInstanceIdentifier getYangRibId() {
490 return this.yangRibId;
494 public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
495 return this.domDataBroker.createTransactionChain(listener);
499 public RIBExtensionConsumerContext getRibExtensions() {
500 return this.extensions;
504 public RIBSupportContextRegistry getRibSupportContext() {
505 return this.ribContextRegistry;
509 public void onGlobalContextUpdated(final SchemaContext context) {
510 this.ribContextRegistry.onSchemaContextUpdated(context);