*/
package org.opendaylight.protocol.bgp.rib.impl;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import org.opendaylight.protocol.bgp.parser.BGPSession;
-import org.opendaylight.protocol.bgp.parser.BGPSessionListener;
+import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
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.PathAttributesBuilder;
-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.PathAttributes1Builder;
-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.update.path.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2;
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;
private static final Logger LOG = LoggerFactory.getLogger(BGPSynchronization.class);
- private static class SyncVariables {
+ @VisibleForTesting
+ static class SyncVariables {
private boolean upd = false;
private boolean eor = false;
}
}
- private final Map<TablesKey, SyncVariables> syncStorage = Maps.newHashMap();
+ @VisibleForTesting
+ public final Map<TablesKey, SyncVariables> syncStorage = Maps.newHashMap();
private final BGPSessionListener listener;
- private final BGPSession session;
-
- public BGPSynchronization(final BGPSession bgpSession, final BGPSessionListener listener, final Set<TablesKey> types) {
+ public BGPSynchronization(final BGPSessionListener listener, final Set<TablesKey> types) {
this.listener = Preconditions.checkNotNull(listener);
- this.session = Preconditions.checkNotNull(bgpSession);
for (final TablesKey type : types) {
this.syncStorage.put(type, new SyncVariables());
/**
* For each received Update message, the upd sync variable needs to be updated to true, for particular AFI/SAFI
* combination. Currently we only assume Unicast SAFI. From the Update message we have to extract the AFI. Each
- * Update message can contain BGP Object with one type of AFI. If the object is BGP Link, BGP Node or BGPPrefix<?>
+ * Update message can contain BGP Object with one type of AFI. If the object is BGP Link, BGP Node or a BGPPrefix
* the AFI is Linkstate. In case of BGPRoute, the AFI depends on the IP Address of the prefix.
*
* @param msg received Update message
TablesKey type = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
boolean isEOR = false;
if (msg.getNlri() == null && msg.getWithdrawnRoutes() == null) {
- if (msg.getPathAttributes() != null) {
- if (msg.getPathAttributes().getAugmentation(PathAttributes1.class) != null) {
- final PathAttributes1 pa = msg.getPathAttributes().getAugmentation(PathAttributes1.class);
+ if (msg.getAttributes() != null) {
+ if (msg.getAttributes().getAugmentation(Attributes1.class) != null) {
+ final Attributes1 pa = msg.getAttributes().getAugmentation(Attributes1.class);
if (pa.getMpReachNlri() != null) {
type = new TablesKey(pa.getMpReachNlri().getAfi(), pa.getMpReachNlri().getSafi());
}
- } else if (msg.getPathAttributes().getAugmentation(PathAttributes2.class) != null) {
- final PathAttributes2 pa = msg.getPathAttributes().getAugmentation(PathAttributes2.class);
+ } else if (msg.getAttributes().getAugmentation(Attributes2.class) != null) {
+ final Attributes2 pa = msg.getAttributes().getAugmentation(Attributes2.class);
if (pa.getMpUnreachNlri() != null) {
type = new TablesKey(pa.getMpUnreachNlri().getAfi(), pa.getMpUnreachNlri().getSafi());
}
+ if (pa.getMpUnreachNlri().getWithdrawnRoutes() == null) {
+ // EOR message contains only MPUnreach attribute and no NLRI
+ isEOR = true;
+ }
}
} else {
+ // true for empty Update Message
isEOR = true;
}
}
+ syncType(type, isEOR);
+ }
+
+ private void syncType(final TablesKey type, final boolean isEOR) {
final SyncVariables s = this.syncStorage.get(type);
if (s == null) {
LOG.warn("BGPTableType was not present in open message : {}", type);
s.setUpd(true);
if (isEOR) {
s.setEorTrue();
+ this.listener.markUptodate(type);
+ LOG.info("BGP Synchronization finished for table {} ", type);
}
}
if (!s.getUpd()) {
s.setEorTrue();
LOG.info("BGP Synchronization finished for table {} ", entry.getKey());
- final Update up = generateEOR(entry.getKey());
- LOG.debug("Sending synchronization message: {}", up);
- this.listener.onMessage(this.session, up);
+ this.listener.markUptodate(entry.getKey());
}
s.setUpd(false);
}
}
}
-
- private Update generateEOR(final TablesKey type) {
- if (type.getAfi().equals(Ipv4AddressFamily.class) && type.getSafi().equals(UnicastSubsequentAddressFamily.class)) {
- return new UpdateBuilder().build();
- }
- return new UpdateBuilder().setPathAttributes(
- new PathAttributesBuilder().addAugmentation(
- PathAttributes1.class,
- new PathAttributes1Builder().setMpReachNlri(
- new MpReachNlriBuilder().setAfi(type.getAfi()).setSafi(type.getSafi()).build()).build()).build()).build();
- }
}