X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=bgp%2Frib-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fprotocol%2Fbgp%2Frib%2Fimpl%2FRIBImpl.java;h=cbe5f6dd676c38c8cb1c7bdd05271590e530f64e;hb=3c78808fd410ca5f4801614c395a1324b84ae5f6;hp=9be3f95101fdfb3dc329cb2a7024f3bab3dc5f3a;hpb=896673218bdc05b7dd7a639bc135817e5088456f;p=bgpcep.git diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java index 9be3f95101..cbe5f6dd67 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java @@ -7,13 +7,14 @@ */ package org.opendaylight.protocol.bgp.rib.impl; -import com.google.common.base.Objects; -import com.google.common.base.Objects.ToStringHelper; +import com.google.common.base.MoreObjects; +import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; @@ -31,11 +32,16 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.controller.md.sal.common.api.data.TransactionChain; import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension; +import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService; +import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain; import org.opendaylight.protocol.bgp.rib.DefaultRibReference; import org.opendaylight.protocol.bgp.rib.impl.spi.AdjRIBsOut; import org.opendaylight.protocol.bgp.rib.impl.spi.AdjRIBsOutRegistration; import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher; import org.opendaylight.protocol.bgp.rib.impl.spi.RIB; +import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry; import org.opendaylight.protocol.bgp.rib.spi.AbstractAdjRIBs; import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsIn; import org.opendaylight.protocol.bgp.rib.spi.BGPObjectComparator; @@ -44,6 +50,13 @@ import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext; import org.opendaylight.protocol.framework.ReconnectStrategyFactory; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.bgp.rib.rib.loc.rib.tables.routes.Ipv4RoutesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.bgp.rib.rib.loc.rib.tables.routes.Ipv6RoutesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.DestinationIpv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.destination.ipv4.Ipv4Prefixes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.destination.ipv4.Ipv4PrefixesBuilder; +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; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.UpdateBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.Nlri; @@ -52,8 +65,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mess import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes2; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.destination.type.DestinationIpv4CaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.destination.type.destination.ipv4._case.DestinationIpv4Builder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlri; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlriBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpUnreachNlri; @@ -70,19 +81,26 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib. import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRibBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.routes.Ipv4RoutesCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.routes.Ipv6RoutesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily; +import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory; +import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ThreadSafe -public final class RIBImpl extends DefaultRibReference implements AutoCloseable, RIB, TransactionChainListener { +public final class RIBImpl extends DefaultRibReference implements AutoCloseable, RIB, TransactionChainListener, SchemaContextListener { private static final Logger LOG = LoggerFactory.getLogger(RIBImpl.class); private static final Update EOR = new UpdateBuilder().build(); private static final TablesKey IPV4_UNICAST_TABLE = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class); + private static final QName RIB_ID_QNAME = QName.cachedReference(QName.create(Rib.QNAME, "id")); /* * FIXME: performance: this needs to be turned into a Peer->offset map. @@ -110,10 +128,16 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable, private final BindingTransactionChain chain; private final AsNumber localAs; private final Ipv4Address bgpIdentifier; + private final ClusterIdentifier clusterId; private final Set localTables; private final RIBTables tables; private final BlockingQueue peers; private final DataBroker dataBroker; + private final DOMDataBroker domDataBroker; + private final RIBExtensionConsumerContext extensions; + private final YangInstanceIdentifier yangRibId; + private final RIBSupportContextRegistryImpl ribContextRegistry; + private final EffectiveRibInWriter efWriter; private final Runnable scheduler = new Runnable() { @Override @@ -145,14 +169,15 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable, } }; - public RIBImpl(final RibId ribId, final AsNumber localAs, final Ipv4Address localBgpId, final RIBExtensionConsumerContext extensions, - final BGPDispatcher dispatcher, final ReconnectStrategyFactory tcpStrategyFactory, - final ReconnectStrategyFactory sessionStrategyFactory, final DataBroker dps, final List localTables) { - super(InstanceIdentifier.builder(BgpRib.class).child(Rib.class, new RibKey(Preconditions.checkNotNull(ribId))).build()); + public RIBImpl(final RibId ribId, final AsNumber localAs, final Ipv4Address localBgpId, final Ipv4Address clusterId, final RIBExtensionConsumerContext extensions, + final BGPDispatcher dispatcher, final ReconnectStrategyFactory tcpStrategyFactory, final BindingCodecTreeFactory codecFactory, + final ReconnectStrategyFactory sessionStrategyFactory, final DataBroker dps, final DOMDataBroker domDataBroker, final List localTables, final GeneratedClassLoadingStrategy classStrategy) { + super(InstanceIdentifier.create(BgpRib.class).child(Rib.class, new RibKey(Preconditions.checkNotNull(ribId)))); this.chain = dps.createTransactionChain(this); this.localAs = Preconditions.checkNotNull(localAs); this.comparator = new BGPObjectComparator(localAs); this.bgpIdentifier = Preconditions.checkNotNull(localBgpId); + this.clusterId = (clusterId == null) ? new ClusterIdentifier(localBgpId) : new ClusterIdentifier(clusterId); this.dispatcher = Preconditions.checkNotNull(dispatcher); this.sessionStrategyFactory = Preconditions.checkNotNull(sessionStrategyFactory); this.tcpStrategyFactory = Preconditions.checkNotNull(tcpStrategyFactory); @@ -160,13 +185,18 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable, this.tables = new RIBTables(extensions); this.peers = new LinkedBlockingQueue<>(); this.dataBroker = dps; + this.domDataBroker = Preconditions.checkNotNull(domDataBroker); + this.extensions = Preconditions.checkNotNull(extensions); + this.ribContextRegistry = RIBSupportContextRegistryImpl.create(extensions, codecFactory, classStrategy); + this.yangRibId = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Rib.QNAME).nodeWithKey(Rib.QNAME, RIB_ID_QNAME, ribId.getValue()).build(); LOG.debug("Instantiating RIB table {} at {}", ribId, getInstanceIdentifier()); final WriteTransaction trans = this.chain.newWriteOnlyTransaction(); // put empty BgpRib if not exists - trans.put(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier(), new RibBuilder().setKey(new RibKey(ribId)).setId(ribId).setLocRib( + trans.put(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier(), + new RibBuilder().setKey(new RibKey(ribId)).setPeer(Collections. emptyList()).setId(ribId).setLocRib( new LocRibBuilder().setTables(Collections. emptyList()).build()).build(), true); for (final BgpTableType t : localTables) { @@ -186,13 +216,32 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable, public void onFailure(final Throwable t) { LOG.error("Failed to initiate RIB {}", getInstanceIdentifier(), t); } + }); + + final PolicyDatabase pd = new PolicyDatabase(localAs.getValue(), localBgpId, this.clusterId); + + final DOMDataBrokerExtension service = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class); + final DOMTransactionChain domChain = this.createPeerChain(this); + this.efWriter = EffectiveRibInWriter.create((DOMDataTreeChangeService) service, this.createPeerChain(this), getYangRibId(), pd, this.ribContextRegistry); + LOG.debug("Effective RIB created."); + + for (final BgpTableType t : localTables) { + final TablesKey key = new TablesKey(t.getAfi(), t.getSafi()); + // create locRibWriter for each table + // FIXME: temporary create writer only for Ipv4 + if (key.getAfi().equals(Ipv4AddressFamily.class) || key.getAfi().equals(Ipv6AddressFamily.class)) { + LocRibWriter.create(this.ribContextRegistry, key, this.createPeerChain(this), getYangRibId(), localAs, (DOMDataTreeChangeService) service, pd); + } + } } + @Deprecated synchronized void initTables(final byte[] remoteBgpId) { } @Override + @Deprecated public synchronized void updateTables(final Peer peer, final Update message) { final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction()); @@ -204,13 +253,17 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable, /* * create MPUnreach for the routes to be handled in the same way as linkstate routes */ + final List prefixes = new ArrayList<>(); + for (final Ipv4Prefix p : wr.getWithdrawnRoutes()) { + prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build()); + } ari.removeRoutes( trans, peer, new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).setWithdrawnRoutes( new WithdrawnRoutesBuilder().setDestinationType( - new DestinationIpv4CaseBuilder().setDestinationIpv4( - new DestinationIpv4Builder().setIpv4Prefixes(wr.getWithdrawnRoutes()).build()).build()).build()).build()); + 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( + new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build()).build()); } else { LOG.debug("Not removing objects from unhandled IPv4 Unicast"); } @@ -242,11 +295,15 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable, /* * create MPReach for the routes to be handled in the same way as linkstate routes */ + final List prefixes = new ArrayList<>(); + for (final Ipv4Prefix p : ar.getNlri()) { + prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build()); + } final MpReachNlriBuilder b = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi( UnicastSubsequentAddressFamily.class).setAdvertizedRoutes( new AdvertizedRoutesBuilder().setDestinationType( new DestinationIpv4CaseBuilder().setDestinationIpv4( - new DestinationIpv4Builder().setIpv4Prefixes(ar.getNlri()).build()).build()).build()); + new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build()); if (attrs != null) { b.setCNextHop(attrs.getCNextHop()); } @@ -296,6 +353,7 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable, }); } + @Deprecated @Override public synchronized void clearTable(final Peer peer, final TablesKey key) { final AdjRIBsIn ari = this.tables.get(key); @@ -319,7 +377,7 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable, @Override public String toString() { - return addToStringAttributes(Objects.toStringHelper(this)).toString(); + return addToStringAttributes(MoreObjects.toStringHelper(this)).toString(); } protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) { @@ -327,12 +385,13 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable, } @SuppressWarnings("unchecked") + @Deprecated protected AdjRIBsIn getTable(final TablesKey key) { return (AdjRIBsIn) this.tables.get(key); } @Override - public void close() throws InterruptedException, ExecutionException { + public synchronized void close() throws InterruptedException, ExecutionException { final WriteTransaction t = this.chain.newWriteOnlyTransaction(); t.delete(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier()); t.submit().get(); @@ -369,6 +428,7 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable, return this.dispatcher; } + @Deprecated @Override public void initTable(final Peer bgpPeer, final TablesKey key) { // FIXME: BUG-196: support graceful restart @@ -428,4 +488,29 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable, } return 0; } + + @Override + public YangInstanceIdentifier getYangRibId() { + return this.yangRibId; + } + + @Override + public DOMTransactionChain createPeerChain(final TransactionChainListener listener) { + return this.domDataBroker.createTransactionChain(listener); + } + + @Override + public RIBExtensionConsumerContext getRibExtensions() { + return this.extensions; + } + + @Override + public RIBSupportContextRegistry getRibSupportContext() { + return this.ribContextRegistry; + } + + @Override + public void onGlobalContextUpdated(final SchemaContext context) { + this.ribContextRegistry.onSchemaContextUpdated(context); + } }