private Map<TablesKey, SendReceive> addPathTableMaps = Collections.emptyMap();
private YangInstanceIdentifier peerPath;
private boolean sessionUp;
+ private boolean llgrSupport;
private Stopwatch peerRestartStopwatch;
private long selectionDeferralTimerSeconds;
private final List<TablesKey> missingEOT = new ArrayList<>();
final RpcProviderRegistry rpcRegistry,
final Set<TablesKey> afiSafisAdvertized,
final Set<TablesKey> afiSafisGracefulAdvertized,
+ final Map<TablesKey, Integer> llGracefulTablesAdvertised,
final BgpPeer bgpPeer) {
super(rib, Ipv4Util.toStringIP(neighborAddress), peerGroupName, role, clusterId,
- localAs, neighborAddress, afiSafisAdvertized, afiSafisGracefulAdvertized, Collections.emptyMap());
+ localAs, neighborAddress, afiSafisAdvertized, afiSafisGracefulAdvertized, llGracefulTablesAdvertised);
this.tableTypeRegistry = requireNonNull(tableTypeRegistry);
this.rib = requireNonNull(rib);
this.rpcRegistry = rpcRegistry;
if (mpReach != null) {
this.ribWriter.updateRoutes(mpReach, nextHopToAttribute(attrs, mpReach));
}
- MpUnreachNlri mpUnreach;
+ final MpUnreachNlri mpUnreach;
if (message.getWithdrawnRoutes() != null) {
mpUnreach = prefixesToMpUnreach(message, isAnyNlriAnnounced);
} else {
final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.mp
.capabilities.graceful.restart.capability.Tables> advertisedTables =
advertisedGracefulRestartCapability.getTables();
+ final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.mp
+ .capabilities.ll.graceful.restart.capability.Tables> advertisedLLTables =
+ session.getAdvertisedLlGracefulRestartCapability().getTables();
+
final List<AddressFamilies> addPathTablesType = session.getAdvertisedAddPathTableTypes();
final Set<BgpTableType> advertizedTableTypes = session.getAdvertisedTableTypes();
LOG.info("Session with peer {} went up with tables {} and Add Path tables {}", this.name,
setAdvertizedGracefulRestartTableTypes(advertisedTables.stream()
.map(t -> new TablesKey(t.getAfi(), t.getSafi())).collect(Collectors.toList()));
}
- final int restartTime = advertisedGracefulRestartCapability.getRestartTime();
- setAfiSafiGracefulRestartState(restartTime, false, restartingLocally);
+ setAfiSafiGracefulRestartState(advertisedGracefulRestartCapability.getRestartTime(), false, restartingLocally);
+
+ final Map<TablesKey, Integer> llTablesReceived;
+ if (advertisedLLTables != null) {
+ llTablesReceived = new HashMap<>();
+ for (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.mp
+ .capabilities.ll.graceful.restart.capability.Tables table : advertisedLLTables) {
+ llTablesReceived.put(new TablesKey(table.getAfi(), table.getSafi()),
+ table.getLongLiveStaleTime().intValue());
+ }
+ } else {
+ llTablesReceived = Collections.emptyMap();
+ }
+ setAdvertizedLlGracefulRestartTableTypes(llTablesReceived);
+
+ if (!llTablesReceived.isEmpty()) {
+ llgrSupport = true;
+ // FIXME: propagate preserved tables
+ } else {
+ // FIXME: clear preserved tables
+ llgrSupport = false;
+ }
+
if (!restartingLocally) {
addBgp4Support();
for (final TablesKey key : this.tables) {
return releaseConnection();
}
+ @Override
+ boolean supportsLLGR() {
+ return this.llgrSupport;
+ }
+
private synchronized void setGracefulPreferences(final boolean localRestarting,
final Set<TablesKey> preservedTables) {
final Set<TablesKey> gracefulTables = this.tables.stream()
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
import org.apache.commons.lang3.StringUtils;
import org.opendaylight.protocol.bgp.parser.spi.MultiprotocolCapabilitiesUtil;
import org.opendaylight.protocol.bgp.parser.spi.RevisedErrorHandlingSupport;
import org.opendaylight.protocol.bgp.rib.impl.BGPPeer;
+import org.opendaylight.protocol.bgp.rib.impl.BgpPeerUtil;
import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences;
peerGroup, hold);
final Set<TablesKey> gracefulTables = GracefulRestartUtil.getGracefulTables(afisSafis.getAfiSafi(),
tableTypeRegistry);
+ final Map<TablesKey, Integer> llGracefulTimers = GracefulRestartUtil
+ .getLlGracefulTimers(afisSafis.getAfiSafi(), tableTypeRegistry);
this.finalCapabilities = getBgpCapabilities(afisSafis, rib, tableTypeRegistry);
- final List<BgpParameters> bgpParameters = getInitialBgpParameters(gracefulTables);
+ final List<BgpParameters> bgpParameters = getInitialBgpParameters(gracefulTables, llGracefulTimers);
final KeyMapping keyMapping = OpenConfigMappingUtil.getNeighborKey(neighbor);
final IpAddress neighborLocalAddress = OpenConfigMappingUtil.getLocalAddress(neighbor.getTransport());
final AsNumber globalAs = rib.getLocalAs();
this.errorHandling = OpenConfigMappingUtil.getRevisedErrorHandling(role, peerGroup, neighbor);
this.bgpPeer = new BGPPeer(tableTypeRegistry, this.neighborAddress, peerGroupName, rib, role, clusterId,
- neighborLocalAs, BgpPeer.this.rpcRegistry, afiSafisAdvertized, gracefulTables, BgpPeer.this);
+ neighborLocalAs, BgpPeer.this.rpcRegistry, afiSafisAdvertized, gracefulTables, llGracefulTimers,
+ BgpPeer.this);
this.prefs = new BGPSessionPreferences(neighborLocalAs, hold, rib.getBgpIdentifier(),
neighborRemoteAs, bgpParameters, getPassword(keyMapping));
this.activeConnection = OpenConfigMappingUtil.isActive(neighbor, peerGroup);
this.keys = keyMapping;
}
- private List<BgpParameters> getInitialBgpParameters(final Set<TablesKey> gracefulTables) {
+ private List<BgpParameters> getInitialBgpParameters(final Set<TablesKey> gracefulTables,
+ final Map<TablesKey, Integer> llGracefulTimers) {
+ final Set<BgpPeerUtil.LlGracefulRestartDTO> llGracefulRestarts = llGracefulTimers.entrySet().stream()
+ .map(entry -> new BgpPeerUtil.LlGracefulRestartDTO(entry.getKey(), entry.getValue(), false))
+ .collect(Collectors.toSet());
return Collections.singletonList(
GracefulRestartUtil.getGracefulBgpParameters(this.finalCapabilities, gracefulTables,
- Collections.emptySet(), gracefulRestartTimer, false, Collections.emptySet()));
+ Collections.emptySet(), gracefulRestartTimer, false, llGracefulRestarts));
}
private synchronized void instantiateServiceInstance() {
final BgpPeer bgpPeer = Mockito.mock(BgpPeer.class);
doReturn(Optional.empty()).when(bgpPeer).getErrorHandling();
return configurePeer(tableRegistry, peerAddress, ribImpl, bgpParameters, peerRole, bgpPeerRegistry,
- afiSafiAdvertised, gracefulAfiSafiAdvertised, bgpPeer);
+ afiSafiAdvertised, gracefulAfiSafiAdvertised, Collections.emptyMap(), bgpPeer);
}
static BGPPeer configurePeer(final BGPTableTypeRegistryConsumer tableRegistry, final Ipv4Address peerAddress,
final RIBImpl ribImpl, final BgpParameters bgpParameters, final PeerRole peerRole,
final BGPPeerRegistry bgpPeerRegistry, final Set<TablesKey> afiSafiAdvertised,
- final Set<TablesKey> gracefulAfiSafiAdvertised, final BgpPeer peer) {
+ final Set<TablesKey> gracefulAfiSafiAdvertised, final Map<TablesKey, Integer> llGracefulTimersAdvertised,
+ final BgpPeer peer) {
final IpAddress ipAddress = new IpAddress(peerAddress);
final BGPPeer bgpPeer = new BGPPeer(tableRegistry, new IpAddress(peerAddress), null, ribImpl, peerRole,
- null, null, null, afiSafiAdvertised, gracefulAfiSafiAdvertised, peer);
+ null, null, null, afiSafiAdvertised, gracefulAfiSafiAdvertised, llGracefulTimersAdvertised, peer);
final List<BgpParameters> tlvs = Lists.newArrayList(bgpParameters);
bgpPeerRegistry.addPeer(ipAddress, bgpPeer,
new BGPSessionPreferences(AS_NUMBER, HOLDTIMER, new BgpId(RIB_ID), AS_NUMBER, tlvs));
Mockito.doReturn(createParameter(false, true, Collections.singletonMap(TABLES_KEY, false))
.getOptionalCapabilities()).when(bgpPeer).getBgpFixedCapabilities();
this.peer = configurePeer(this.tableRegistry, PEER1, this.ribImpl, parameters, PeerRole.Ibgp,
- this.serverRegistry, afiSafiAdvertised, gracefulAfiSafiAdvertised, bgpPeer);
+ this.serverRegistry, afiSafiAdvertised, gracefulAfiSafiAdvertised, Collections.emptyMap(), bgpPeer);
this.session = createPeerSession(PEER1, parameters, this.listener);
}