Propagate LLGR configuration 22/78822/1
authorRobert Varga <robert.varga@pantheon.tech>
Sat, 15 Dec 2018 17:53:42 +0000 (18:53 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Sat, 15 Dec 2018 18:27:32 +0000 (19:27 +0100)
Add BGPPeer awareness of LLGR, with basic configuration and
negotiation, without following required mechanics yet.

JIRA: BGPCEP-495
Change-Id: I659fcdb35ffc9884f3cfb579d98495cee48d468d
Signed-off-by: Matej Perina <matej.perina@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpPeer.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/AbstractAddPathTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/GracefulRestartTest.java

index c739f8beb80b668d15ff51540f0643a018d26915..1a7eb3c500ce15ccbb233f0788626bcfac2c63aa 100644 (file)
@@ -144,6 +144,7 @@ public class BGPPeer extends AbstractPeer implements BGPSessionListener {
     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<>();
@@ -159,9 +160,10 @@ public class BGPPeer extends AbstractPeer implements BGPSessionListener {
             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;
@@ -308,7 +310,7 @@ public class BGPPeer extends AbstractPeer implements BGPSessionListener {
         if (mpReach != null) {
             this.ribWriter.updateRoutes(mpReach, nextHopToAttribute(attrs, mpReach));
         }
-        MpUnreachNlri mpUnreach;
+        final MpUnreachNlri mpUnreach;
         if (message.getWithdrawnRoutes() != null) {
             mpUnreach = prefixesToMpUnreach(message, isAnyNlriAnnounced);
         } else {
@@ -360,6 +362,10 @@ public class BGPPeer extends AbstractPeer implements BGPSessionListener {
         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,
@@ -419,8 +425,29 @@ public class BGPPeer extends AbstractPeer implements BGPSessionListener {
             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) {
@@ -669,6 +696,11 @@ public class BGPPeer extends AbstractPeer implements BGPSessionListener {
         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()
index 052ac37a235f22cbfb5a28f16ab955d222f670ce..925a4c79518dcc06d8918d283032fdff3a4521f9 100644 (file)
@@ -18,9 +18,11 @@ import java.net.InetSocketAddress;
 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;
@@ -31,6 +33,7 @@ import org.opendaylight.protocol.bgp.parser.BgpExtendedMessageUtil;
 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;
@@ -263,8 +266,10 @@ public class BgpPeer implements PeerBean, BGPPeerStateConsumer {
                     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();
@@ -279,7 +284,8 @@ public class BgpPeer implements PeerBean, BGPPeerStateConsumer {
 
             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);
@@ -296,10 +302,14 @@ public class BgpPeer implements PeerBean, BGPPeerStateConsumer {
             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() {
index 7ba5afb054f7dea2819f20f0b276b1003c8f617c..b4dc61d032946b8dc7204d04f636ff1371c3c283 100644 (file)
@@ -263,17 +263,18 @@ public abstract class AbstractAddPathTest extends DefaultRibPoliciesMockTest {
         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));
index c986d90a79ec822938d73fbd555e97b27d30045c..873e6a51d0026e24b5baf454dce830ed4a995170 100644 (file)
@@ -126,7 +126,7 @@ public class GracefulRestartTest extends AbstractAddPathTest {
         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);
     }