import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsIn;
import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
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;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.WithdrawnRoutes;
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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
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.types.rev130919.Ipv4AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ThreadSafe
public class RIBImpl {
private static final Logger LOG = LoggerFactory.getLogger(RIBImpl.class);
+ private static final Update EOR = new UpdateBuilder().build();
private final DataProviderService dps;
private final RIBTables tables;
synchronized void updateTables(final BGPPeer peer, final Update message) {
final DataModificationTransaction trans = this.dps.beginTransaction();
- // FIXME: detect and handle end-of-RIB markers
+ if (EOR.equals(message)) {
+ final AdjRIBsIn ari = this.tables.getOrCreate(trans, new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
+ if (ari != null) {
+ ari.markUptodate(trans, peer);
+ } else {
+ LOG.debug("End-of-RIB for IPv4 Unicast ignored");
+ }
+ return;
+ }
- // remove(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class,
- // trans, peer, message.getWithdrawnRoutes().getWithdrawnRoutes().iterator());
+ final WithdrawnRoutes wr = message.getWithdrawnRoutes();
+ if (wr != null) {
+ final AdjRIBsIn ari = this.tables.getOrCreate(trans, new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
+ if (ari != null) {
+ ari.removeRoutes(trans, peer, new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).setWithdrawnRoutes(
+ new WithdrawnRoutesBuilder().setDestinationType(new DestinationIpv4Builder().setIpv4Prefixes(wr.getWithdrawnRoutes()).build()).build()).build());
+ } else {
+ LOG.debug("Not removing objects from unhandled IPv4 Unicast");
+ }
+ }
final PathAttributes attrs = message.getPathAttributes();
final PathAttributes2 mpu = attrs.getAugmentation(PathAttributes2.class);
if (mpu != null) {
final MpUnreachNlri nlri = mpu.getMpUnreachNlri();
- final AdjRIBsIn ari = this.tables.getOrCreate(new TablesKey(nlri.getAfi(), nlri.getSafi()));
+ final AdjRIBsIn ari = this.tables.getOrCreate(trans, new TablesKey(nlri.getAfi(), nlri.getSafi()));
if (ari != null) {
ari.removeRoutes(trans, peer, nlri);
} else {
}
}
- // add(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class,
- // trans, peer, message.getNlri().getNlri().iterator(), attrs);
+ final Nlri ar = message.getNlri();
+ if (ar != null) {
+ final AdjRIBsIn ari = this.tables.getOrCreate(trans, new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
+ if (ari != null) {
+ ari.addRoutes(trans, peer, new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).
+ setCNextHop(attrs.getCNextHop()).setAdvertizedRoutes(
+ new AdvertizedRoutesBuilder().setDestinationType(new DestinationIpv4Builder().setIpv4Prefixes(ar.getNlri()).build()).build()).build(), attrs);
+ } else {
+ LOG.debug("Not adding objects from unhandled IPv4 Unicast");
+ }
+ }
final PathAttributes1 mpr = message.getPathAttributes().getAugmentation(PathAttributes1.class);
if (mpr != null) {
final MpReachNlri nlri = mpr.getMpReachNlri();
- final AdjRIBsIn ari = this.tables.getOrCreate(new TablesKey(nlri.getAfi(), nlri.getSafi()));
+ final AdjRIBsIn ari = this.tables.getOrCreate(trans, new TablesKey(nlri.getAfi(), nlri.getSafi()));
if (ari != null) {
ari.addRoutes(trans, peer, nlri, attrs);
+ if (message.equals(ari.endOfRib())) {
+ ari.markUptodate(trans, peer);
+ }
} else {
LOG.debug("Not adding objects from unhandled NLRI {}", nlri);
}
}
- Futures.addCallback(JdkFutureAdapters.listenInPoolThread(trans.commit()),
- new FutureCallback<RpcResult<TransactionStatus>>() {
+ Futures.addCallback(JdkFutureAdapters.listenInPoolThread(trans.commit()), new FutureCallback<RpcResult<TransactionStatus>>() {
@Override
public void onSuccess(final RpcResult<TransactionStatus> result) {
- // Nothing to do
+ LOG.debug("RIB modification successfully committed.");
}
@Override
final DataModificationTransaction trans = this.dps.beginTransaction();
ari.clear(trans, peer);
- Futures.addCallback(JdkFutureAdapters.listenInPoolThread(trans.commit()),
- new FutureCallback<RpcResult<TransactionStatus>>() {
+ Futures.addCallback(JdkFutureAdapters.listenInPoolThread(trans.commit()), new FutureCallback<RpcResult<TransactionStatus>>() {
@Override
public void onSuccess(final RpcResult<TransactionStatus> result) {
// Nothing to do