+
+ @Override
+ public synchronized ListenableFuture<?> restartGracefully(final long selectionDeferralTimerSeconds) {
+ final Set<TablesKey> tablesToPreserve = getGracefulTables();
+ if (tablesToPreserve == null || tablesToPreserve.isEmpty()) {
+ LOG.info("Peer {} is not capable of graceful restart or have no matching graceful tables.", this.peerId);
+ return Futures.immediateFailedFuture(new UnsupportedOperationException(
+ "Peer is not capable of graceful restart"));
+ }
+ setGracefulPreferences(true, tablesToPreserve);
+ this.currentSelectionDeferralTimerSeconds = selectionDeferralTimerSeconds;
+ setLocalRestartingState(true);
+ 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()
+ .filter(this::isGracefulRestartAdvertized)
+ .collect(Collectors.toSet());
+ final BgpParameters bgpParameters = GracefulRestartUtil.getGracefulBgpParameters(
+ this.bgpPeer.getBgpFixedCapabilities(), gracefulTables, preservedTables,
+ this.bgpPeer.getGracefulRestartTimer(), localRestarting, Collections.emptySet());
+ final BGPSessionPreferences oldPrefs = this.rib.getDispatcher().getBGPPeerRegistry()
+ .getPeerPreferences(getNeighborAddress());
+ final BGPSessionPreferences newPrefs = new BGPSessionPreferences(
+ oldPrefs.getMyAs(),
+ oldPrefs.getHoldTime(),
+ oldPrefs.getBgpId(),
+ oldPrefs.getExpectedRemoteAs(),
+ Collections.singletonList(bgpParameters),
+ oldPrefs.getMd5Password());
+ this.rib.getDispatcher().getBGPPeerRegistry()
+ .updatePeerPreferences(getNeighborAddress(), newPrefs);
+ }