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 Ipv4Address 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, 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 ? localBgpId : 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, new ClusterIdentifier(localBgpId));
195 /*if (clusterId == null) {
196 clusterId is not present, fallback to bgpId
197 pd = new PolicyDatabase(localAs.getValue(), localBgpId, new ClusterIdentifier(localBgpId));
199 pd = new PolicyDatabase(as, bgpId, clusterId);
202 final DOMDataBrokerExtension service = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
203 final DOMTransactionChain domChain = this.createPeerChain(this);
205 EffectiveRibInWriter.create((DOMDataTreeChangeService) service, domChain, getYangRibId(), pd, this.ribContextRegistry);
207 // put empty BgpRib if not exists
208 trans.put(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier(),
209 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(
210 new LocRibBuilder().setTables(Collections.<Tables> emptyList()).build()).build(), true);
212 for (final BgpTableType t : localTables) {
213 final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
214 if (this.tables.create(trans, this, key) == null) {
215 LOG.debug("Did not create local table for unhandled table type {}", t);
219 Futures.addCallback(trans.submit(), new FutureCallback<Void>() {
221 public void onSuccess(final Void result) {
222 LOG.trace("Change committed successfully");
226 public void onFailure(final Throwable t) {
227 LOG.error("Failed to initiate RIB {}", getInstanceIdentifier(), t);
233 synchronized void initTables(final byte[] remoteBgpId) {
237 public synchronized void updateTables(final Peer peer, final Update message) {
238 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
240 if (!EOR.equals(message)) {
241 final WithdrawnRoutes wr = message.getWithdrawnRoutes();
243 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
246 * create MPUnreach for the routes to be handled in the same way as linkstate routes
248 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
249 for (final Ipv4Prefix p : wr.getWithdrawnRoutes()) {
250 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
255 new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).setWithdrawnRoutes(
256 new WithdrawnRoutesBuilder().setDestinationType(
257 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(
258 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build()).build());
260 LOG.debug("Not removing objects from unhandled IPv4 Unicast");
264 final PathAttributes attrs = message.getPathAttributes();
266 final PathAttributes2 mpu = attrs.getAugmentation(PathAttributes2.class);
268 final MpUnreachNlri nlri = mpu.getMpUnreachNlri();
269 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
270 // EOR messages do not contain withdrawn routes
271 if (nlri.getWithdrawnRoutes() != null) {
273 ari.removeRoutes(trans, peer, nlri);
275 LOG.debug("Not removing objects from unhandled NLRI {}", nlri);
278 ari.markUptodate(trans, peer);
283 final Nlri ar = message.getNlri();
285 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
288 * create MPReach for the routes to be handled in the same way as linkstate routes
290 final List<Ipv4Prefixes> prefixes = new ArrayList<>();
291 for (final Ipv4Prefix p : ar.getNlri()) {
292 prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
294 final MpReachNlriBuilder b = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(
295 UnicastSubsequentAddressFamily.class).setAdvertizedRoutes(
296 new AdvertizedRoutesBuilder().setDestinationType(
297 new DestinationIpv4CaseBuilder().setDestinationIpv4(
298 new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build());
300 b.setCNextHop(attrs.getCNextHop());
303 ari.addRoutes(trans, peer, b.build(), attrs);
305 LOG.debug("Not adding objects from unhandled IPv4 Unicast");
310 final PathAttributes1 mpr = attrs.getAugmentation(PathAttributes1.class);
312 final MpReachNlri nlri = mpr.getMpReachNlri();
314 final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
316 if (message.equals(ari.endOfRib())) {
317 ari.markUptodate(trans, peer);
319 ari.addRoutes(trans, peer, nlri, attrs);
322 LOG.debug("Not adding objects from unhandled NLRI {}", nlri);
327 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
329 ari.markUptodate(trans, peer);
331 LOG.debug("End-of-RIB for IPv4 Unicast ignored");
335 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
337 public void onSuccess(final Void result) {
338 LOG.debug("RIB modification successfully committed.");
342 public void onFailure(final Throwable t) {
343 LOG.error("Failed to commit RIB modification", t);
349 public synchronized void clearTable(final Peer peer, final TablesKey key) {
350 final AdjRIBsIn<?, ?> ari = this.tables.get(key);
352 final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
353 ari.clear(trans, peer);
355 Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
357 public void onSuccess(final Void result) {
358 LOG.trace("Table {} cleared successfully", key);
362 public void onFailure(final Throwable t) {
363 LOG.error("Failed to clear table {}", key, t);
370 public String toString() {
371 return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
374 protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
375 return toStringHelper;
378 @SuppressWarnings("unchecked")
379 protected <K, V extends Route> AdjRIBsIn<K, V> getTable(final TablesKey key) {
380 return (AdjRIBsIn<K, V>) this.tables.get(key);
384 public synchronized void close() throws InterruptedException, ExecutionException {
385 final WriteTransaction t = this.chain.newWriteOnlyTransaction();
386 t.delete(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier());
392 public AsNumber getLocalAs() {
397 public Ipv4Address getBgpIdentifier() {
398 return this.bgpIdentifier;
402 public Set<? extends BgpTableType> getLocalTables() {
403 return this.localTables;
407 public ReconnectStrategyFactory getTcpStrategyFactory() {
408 return this.tcpStrategyFactory;
412 public ReconnectStrategyFactory getSessionStrategyFactory() {
413 return this.sessionStrategyFactory;
417 public BGPDispatcher getDispatcher() {
418 return this.dispatcher;
422 public void initTable(final Peer bgpPeer, final TablesKey key) {
423 // FIXME: BUG-196: support graceful restart
427 public AdjRIBsOutRegistration registerRIBsOut(final Peer peer, final AdjRIBsOut aro) {
428 final AdjRIBsOutRegistration reg = new AdjRIBsOutRegistration(aro) {
430 protected void removeRegistration() {
431 RIBImpl.this.ribOuts.remove(peer, aro);
435 this.ribOuts.put(peer, aro);
436 LOG.debug("Registering this peer {} to RIB-Out {}", peer, this.ribOuts);
438 this.peers.put(peer);
439 new Thread(this.scheduler).start();
440 } catch (final InterruptedException e) {
447 public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction, final Throwable cause) {
448 LOG.error("Broken chain in RIB {} transaction {}", getInstanceIdentifier(), transaction.getIdentifier(), cause);
452 public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
453 LOG.info("RIB {} closed successfully", getInstanceIdentifier());
457 public long getRoutesCount(final TablesKey key) {
459 final Optional<Tables> tableMaybe = this.dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL,
460 getInstanceIdentifier().child(LocRib.class).child(Tables.class, key)).checkedGet();
461 if (tableMaybe.isPresent()) {
462 final Tables table = tableMaybe.get();
463 if (table.getRoutes() instanceof Ipv4RoutesCase) {
464 final Ipv4RoutesCase routesCase = (Ipv4RoutesCase) table.getRoutes();
465 if (routesCase.getIpv4Routes() != null && routesCase.getIpv4Routes().getIpv4Route() != null) {
466 return routesCase.getIpv4Routes().getIpv4Route().size();
468 } else if (table.getRoutes() instanceof Ipv6RoutesCase) {
469 final Ipv6RoutesCase routesCase = (Ipv6RoutesCase) table.getRoutes();
470 if (routesCase.getIpv6Routes() != null && routesCase.getIpv6Routes().getIpv6Route() != null) {
471 return routesCase.getIpv6Routes().getIpv6Route().size();
475 } catch (final ReadFailedException e) {
482 public YangInstanceIdentifier getYangRibId() {
483 return this.yangRibId;
487 public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
488 return this.domDataBroker.createTransactionChain(listener);
492 public RIBExtensionConsumerContext getRibExtensions() {
493 return this.extensions;
497 public RIBSupportContextRegistry getRibSupportContext() {
498 return this.ribContextRegistry;
502 public void onGlobalContextUpdated(final SchemaContext context) {
503 this.ribContextRegistry.onSchemaContextUpdated(context);