Add decoder constraint based on treat-as-withdrawn configuration 61/78561/24
authorMatej Perina <matej.perina@pantheon.tech>
Sun, 9 Dec 2018 10:15:13 +0000 (11:15 +0100)
committerRobert Varga <nite@hq.sk>
Fri, 14 Dec 2018 07:28:45 +0000 (07:28 +0000)
Uses openconfig peer/peer-group -> error-handling ->
treat-as-withdrawn for configuring whether treat-as-withdrawn
procedures should take place.

JIRA: BGPCEP-359
Change-Id: I0fd34df7fbb500b4c7fa7012b2f0cfbef8c1f5e1
Signed-off-by: Matej Perina <matej.perina@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
14 files changed:
bgp/openconfig-api/src/main/yang/openconfig-bgp.yang
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/RevisedErrorHandlingSupportImpl.java
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/BGPSessionImpl.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/BgpPeer.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/config/OpenConfigMappingUtil.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
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/ParserToSalTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/PeerTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/SynchronizationAndExceptionTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/config/OpenConfigMappingUtilTest.java
bgp/rib-mock/src/main/java/org/opendaylight/protocol/bgp/rib/mock/EventBusRegistration.java
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/BGPSession.java

index ab6bdb328156557f1354c7934620b4aeb918a7d1..64303eb13dd1964141b9a35ddb1157d14c785b08 100644 (file)
@@ -308,9 +308,9 @@ module openconfig-bgp {
       default "false";
       description
         "Specify whether erroneous UPDATE messages for which the
-        NLRI can be extracted are reated as though the NLRI is
+        NLRI can be extracted are treated as though the NLRI is
         withdrawn - avoiding session reset";
-      reference "draft-ietf-idr-error-handling-16";
+      reference "https://tools.ietf.org/html/rfc7606";
     }
   }
 
index eb7c2c541cde6bed256832fb19ec863842441c14..c5cded52af86091881f9f71b8d4297536fe19a1f 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.protocol.bgp.parser.spi.pojo;
 
+import com.google.common.base.MoreObjects;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.opendaylight.protocol.bgp.parser.spi.RevisedErrorHandlingSupport;
 
@@ -33,4 +34,9 @@ public final class RevisedErrorHandlingSupportImpl implements RevisedErrorHandli
     public boolean isExternalPeer() {
         return externalPeer;
     }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this).add("externalPeer", externalPeer).toString();
+    }
 }
index fc79c5de97a0d27ed54eeda446650370fc42fb74..695ae4e0e477a8e1dddb58d9db97d784a0121d33 100644 (file)
@@ -45,6 +45,7 @@ import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.impl.message.update.LocalPreferenceAttributeParser;
 import org.opendaylight.protocol.bgp.parser.spi.MessageUtil;
+import org.opendaylight.protocol.bgp.parser.spi.RevisedErrorHandlingSupport;
 import org.opendaylight.protocol.bgp.rib.impl.config.BgpPeer;
 import org.opendaylight.protocol.bgp.rib.impl.config.GracefulRestartUtil;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences;
@@ -166,19 +167,6 @@ public class BGPPeer extends AbstractPeer implements BGPSessionListener {
         this.bgpPeer = bgpPeer;
     }
 
-    BGPPeer(
-            final BGPTableTypeRegistryConsumer tableTypeRegistry,
-            final IpAddress neighborAddress,
-            final RIB rib,
-            final PeerRole role,
-            final RpcProviderRegistry rpcRegistry,
-            final Set<TablesKey> afiSafisAdvertized,
-            final Set<TablesKey> afiSafisGracefulAdvertized) {
-        this(tableTypeRegistry, neighborAddress, null, rib, role, null, null, rpcRegistry,
-                afiSafisAdvertized, afiSafisGracefulAdvertized, null);
-    }
-
-
     private static Attributes nextHopToAttribute(final Attributes attrs, final MpReachNlri mpReach) {
         if (attrs.getCNextHop() == null && mpReach.getCNextHop() != null) {
             final AttributesBuilder attributesBuilder = new AttributesBuilder(attrs);
@@ -436,6 +424,12 @@ public class BGPPeer extends AbstractPeer implements BGPSessionListener {
                 createAdjRibOutListener(key, true);
             }
         }
+
+        // SpotBugs does not grok Optional.ifPresent() and thinks we are using unsynchronized access
+        final Optional<RevisedErrorHandlingSupport> errorHandling = this.bgpPeer.getErrorHandling();
+        if (errorHandling.isPresent()) {
+            this.session.addDecoderConstraint(RevisedErrorHandlingSupport.class, errorHandling.get());
+        }
     }
 
     private boolean isRestartingGracefully() {
index 06bcbde13f0c091c67982095696a3a5904d4c8be..c77a1ad49730884af44a8a6868a62e4779cb0d19 100644 (file)
@@ -19,7 +19,6 @@ import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelFutureListener;
 import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelPipeline;
 import io.netty.channel.SimpleChannelInboundHandler;
 import java.io.IOException;
 import java.nio.channels.NonWritableChannelException;
@@ -39,6 +38,7 @@ import org.opendaylight.protocol.bgp.parser.BgpExtendedMessageUtil;
 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
 import org.opendaylight.protocol.bgp.parser.GracefulRestartUtil;
 import org.opendaylight.protocol.bgp.parser.spi.MultiPathSupport;
+import org.opendaylight.protocol.bgp.parser.spi.PeerConstraint;
 import org.opendaylight.protocol.bgp.parser.spi.pojo.MultiPathSupportImpl;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPMessagesListener;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
@@ -184,10 +184,8 @@ public class BGPSessionImpl extends SimpleChannelInboundHandler<Notification> im
         this.addPathTypes = addPathCapabilitiesList;
 
         if (!this.addPathTypes.isEmpty()) {
-            final ChannelPipeline pipeline = this.channel.pipeline();
-            final BGPByteToMessageDecoder decoder = pipeline.get(BGPByteToMessageDecoder.class);
-            decoder.addDecoderConstraint(MultiPathSupport.class,
-                    MultiPathSupportImpl.createParserMultiPathSupport(this.addPathTypes));
+            addDecoderConstraint(MultiPathSupport.class,
+                MultiPathSupportImpl.createParserMultiPathSupport(this.addPathTypes));
         }
 
         if (this.holdTimerValue != 0) {
@@ -565,4 +563,9 @@ public class BGPSessionImpl extends SimpleChannelInboundHandler<Notification> im
     public void registerMessagesCounter(final BGPMessagesListener bgpMessagesListener) {
         this.sessionState.registerMessagesCounter(bgpMessagesListener);
     }
+
+    @Override
+    public <T extends PeerConstraint> void addDecoderConstraint(final Class<T> constraintClass, final T constraint) {
+        this.channel.pipeline().get(BGPByteToMessageDecoder.class).addDecoderConstraint(constraintClass, constraint);
+    }
 }
index 50661d60f6c10f621cf6e5a8aa2b2f4b6e1ea82e..b4be227693f81fc37b4880f12f4d4062bef9808c 100644 (file)
@@ -21,6 +21,7 @@ import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
+import javax.annotation.Nullable;
 import javax.annotation.concurrent.GuardedBy;
 import org.apache.commons.lang3.StringUtils;
 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
@@ -28,6 +29,7 @@ import org.opendaylight.mdsal.common.api.CommitInfo;
 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
 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.spi.BGPDispatcher;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
@@ -226,6 +228,7 @@ public class BgpPeer implements PeerBean, BGPPeerStateConsumer {
         private boolean isServiceInstantiated;
         private final List<OptionalCapabilities> finalCapabilities;
         private final int gracefulRestartTimer;
+        private final RevisedErrorHandlingSupport errorHandling;
 
 
         private BgpPeerSingletonService(final RIB rib, final Neighbor neighbor, final InstanceIdentifier<Bgp> bgpIid,
@@ -252,6 +255,7 @@ public class BgpPeer implements PeerBean, BGPPeerStateConsumer {
             final Set<TablesKey> afiSafisAdvertized = OpenConfigMappingUtil
                     .toTableKey(afisSafis.getAfiSafi(), tableTypeRegistry);
             final PeerRole role = OpenConfigMappingUtil.toPeerRole(neighbor, peerGroup);
+
             final ClusterIdentifier clusterId = OpenConfigMappingUtil
                     .getNeighborClusterIdentifier(neighbor.getRouteReflector(), peerGroup);
             final int hold = OpenConfigMappingUtil.getHoldTimer(neighbor, peerGroup);
@@ -273,6 +277,7 @@ public class BgpPeer implements PeerBean, BGPPeerStateConsumer {
                 neighborLocalAs = globalAs;
             }
 
+            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);
             this.prefs = new BGPSessionPreferences(neighborLocalAs, hold, rib.getBgpIdentifier(),
@@ -336,4 +341,9 @@ public class BgpPeer implements PeerBean, BGPPeerStateConsumer {
     public synchronized int getGracefulRestartTimer() {
         return this.bgpPeerSingletonService.gracefulRestartTimer;
     }
+
+    @Nullable
+    public synchronized Optional<RevisedErrorHandlingSupport> getErrorHandling() {
+        return Optional.ofNullable(this.bgpPeerSingletonService.errorHandling);
+    }
 }
index 418b383cb43571155b05688b99f0a620987aca42..7190b1d63395cbbd061bf051cba360b43683a471 100644 (file)
@@ -25,6 +25,8 @@ import org.opendaylight.protocol.bgp.mode.api.PathSelectionMode;
 import org.opendaylight.protocol.bgp.mode.impl.add.all.paths.AllPathSelection;
 import org.opendaylight.protocol.bgp.mode.impl.add.n.paths.AddPathBestNPathSelection;
 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
+import org.opendaylight.protocol.bgp.parser.spi.RevisedErrorHandlingSupport;
+import org.opendaylight.protocol.bgp.parser.spi.pojo.RevisedErrorHandlingSupportImpl;
 import org.opendaylight.protocol.concepts.KeyMapping;
 import org.opendaylight.protocol.util.Ipv4Util;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.BgpCommonAfiSafiList;
@@ -34,6 +36,7 @@ import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNe
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborGroup;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborTransportConfig;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.graceful.restart.GracefulRestart;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ErrorHandling;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.RouteReflector;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Timers;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Transport;
@@ -479,4 +482,40 @@ final class OpenConfigMappingUtil {
         }
         return null;
     }
+
+    @Nullable
+    static RevisedErrorHandlingSupport getRevisedErrorHandling(final PeerRole role,final PeerGroup peerGroup,
+            final Neighbor neighbor) {
+        Boolean enabled = getRevisedErrorHandling(neighbor);
+        if (enabled == null) {
+            enabled = getRevisedErrorHandling(peerGroup);
+        }
+        if (!Boolean.TRUE.equals(enabled)) {
+            return null;
+        }
+        switch (role) {
+            case Ebgp:
+                return RevisedErrorHandlingSupportImpl.forExternalPeer();
+            case Ibgp:
+            case Internal:
+            case RrClient:
+                return RevisedErrorHandlingSupportImpl.forInternalPeer();
+            default:
+                throw new IllegalStateException("Unhandled role " + role);
+        }
+    }
+
+    @Nullable
+    private static @org.eclipse.jdt.annotation.Nullable Boolean getRevisedErrorHandling(final BgpNeighborGroup group) {
+        if (group == null) {
+            return null;
+        }
+        final ErrorHandling errorHandling = group.getErrorHandling();
+        if (errorHandling == null) {
+            return null;
+        }
+        final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.error.handling
+            .Config config = errorHandling.getConfig();
+        return config == null ? null : config.isTreatAsWithdraw();
+    }
 }
index 769a73185bfb5a90dc0e386d1d0a2b8035aec505..96b016f18952a3ba39aec730bd5056a80105d99c 100644 (file)
@@ -21,6 +21,7 @@ import java.net.InetSocketAddress;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
@@ -259,8 +260,10 @@ public abstract class AbstractAddPathTest extends DefaultRibPoliciesMockTest {
             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 bgpPeer = Mockito.mock(BgpPeer.class);
+        doReturn(Optional.empty()).when(bgpPeer).getErrorHandling();
         return configurePeer(tableRegistry, peerAddress, ribImpl, bgpParameters, peerRole, bgpPeerRegistry,
-                afiSafiAdvertised, gracefulAfiSafiAdvertised, null);
+                afiSafiAdvertised, gracefulAfiSafiAdvertised, bgpPeer);
     }
 
     static BGPPeer configurePeer(final BGPTableTypeRegistryConsumer tableRegistry,
index cf6842e762d5a2ea581457bc8a0d7036c2394787..9e08f4919da129a32aded2b12fa003faaa4968af 100644 (file)
@@ -28,6 +28,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.stream.Collectors;
@@ -121,6 +122,7 @@ public class GracefulRestartTest extends AbstractAddPathTest {
         afiSafiAdvertised.add(IPV6_TABLES_KEY);
         final BgpPeer bgpPeer = Mockito.mock(BgpPeer.class);
         Mockito.doReturn(GRACEFUL_RESTART_TIME).when(bgpPeer).getGracefulRestartTimer();
+        Mockito.doReturn(Optional.empty()).when(bgpPeer).getErrorHandling();
         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,
index c8f960e88bb0b614e129b3a274950a6fb1b382db..45d9fc35150c86cb1bc248dc13718525c0c5777f 100755 (executable)
@@ -116,8 +116,8 @@ public class ParserToSalTest extends DefaultRibPoliciesMockTest {
         rib.instantiateServiceInstance();
         assertTablesExists(tables);
         rib.onGlobalContextUpdated(this.schemaService.getGlobalContext());
-        final BGPPeer peer = new BGPPeer(this.tableRegistry, this.localAddress, rib, PeerRole.Ibgp, null,
-                Collections.emptySet(), Collections.emptySet());
+        final BGPPeer peer = AbstractAddPathTest.configurePeer(this.tableRegistry, this.localAddress.getIpv4Address(),
+                rib, null, PeerRole.Ibgp, new StrictBGPPeerRegistry());
         peer.instantiateServiceInstance();
         final ListenerRegistration<?> reg = this.mock.registerUpdateListener(peer);
         reg.close();
@@ -134,8 +134,8 @@ public class ParserToSalTest extends DefaultRibPoliciesMockTest {
         rib.instantiateServiceInstance();
         rib.onGlobalContextUpdated(this.schemaService.getGlobalContext());
         assertTablesExists(tables);
-        final BGPPeer peer = new BGPPeer(this.tableRegistry, this.localAddress, rib, PeerRole.Ibgp, null,
-                Collections.emptySet(), Collections.emptySet());
+        final BGPPeer peer = AbstractAddPathTest.configurePeer(this.tableRegistry, this.localAddress.getIpv4Address(),
+                rib, null, PeerRole.Ibgp, new StrictBGPPeerRegistry());
         peer.instantiateServiceInstance();
         final ListenerRegistration<?> reg = this.mock.registerUpdateListener(peer);
         reg.close();
index 01d5ca65c66c9b18945d2f6ae9005d3aab75dadd..79c1d7ce90d3261908e48ce03e0e873144db9336 100644 (file)
@@ -137,8 +137,8 @@ public class PeerTest extends AbstractRIBTestSetup {
 
     @Test
     public void testClassicPeer() throws Exception {
-        this.classic = new BGPPeer(this.tableRegistry, this.neighborAddress, getRib(), PeerRole.Ibgp, null,
-                Collections.emptySet(), Collections.emptySet());
+        this.classic = AbstractAddPathTest.configurePeer(this.tableRegistry, this.neighborAddress.getIpv4Address(),
+                getRib(), null, PeerRole.Ibgp, new StrictBGPPeerRegistry());
         this.classic.instantiateServiceInstance();
         this.mockSession();
         assertEquals(this.neighborAddress.getIpv4Address().getValue(), this.classic.getName());
@@ -179,8 +179,8 @@ public class PeerTest extends AbstractRIBTestSetup {
         assertEquals(3, this.routes.size());
 
         //create new peer so that it gets advertized routes from RIB
-        final BGPPeer testingPeer = new BGPPeer(this.tableRegistry, this.neighborAddress, getRib(), PeerRole.Ibgp,
-                null, Collections.emptySet(), Collections.emptySet());
+        final BGPPeer testingPeer = AbstractAddPathTest.configurePeer(this.tableRegistry, this.neighborAddress.getIpv4Address(),
+                getRib(), null, PeerRole.Ibgp, new StrictBGPPeerRegistry());
         testingPeer.instantiateServiceInstance();
         testingPeer.onSessionUp(this.session);
         assertEquals(3, this.routes.size());
index 42e4dc9198e475319459f013b52e997606148a6f..4d94494eac38806149bcee0d6255b2fd7e9b29f8 100644 (file)
@@ -219,8 +219,8 @@ public class SynchronizationAndExceptionTest extends AbstractAddPathTest {
         ribImpl.instantiateServiceInstance();
         ribImpl.onGlobalContextUpdated(this.schemaService.getGlobalContext());
 
-        final BGPPeer bgpPeer = new BGPPeer(this.tableRegistry, neighbor, ribImpl, PeerRole.Ibgp, null,
-                AFI_SAFIS_ADVERTIZED, Collections.emptySet());
+        final BGPPeer bgpPeer = AbstractAddPathTest.configurePeer(this.tableRegistry, neighbor.getIpv4Address(), ribImpl,
+                null, PeerRole.Ibgp, this.serverRegistry, AFI_SAFIS_ADVERTIZED, Collections.emptySet());
         bgpPeer.instantiateServiceInstance();
         final BGPSessionImpl bgpSession = new BGPSessionImpl(bgpPeer, this.speakerListener, this.classicOpen,
                 this.classicOpen.getHoldTimer(), null);
@@ -268,8 +268,8 @@ public class SynchronizationAndExceptionTest extends AbstractAddPathTest {
         ribImpl.instantiateServiceInstance();
         ribImpl.onGlobalContextUpdated(this.schemaService.getGlobalContext());
 
-        final BGPPeer bgpPeer = new BGPPeer(this.tableRegistry, neighbor, ribImpl, PeerRole.Ibgp, null,
-                AFI_SAFIS_ADVERTIZED, Collections.emptySet());
+        final BGPPeer bgpPeer = AbstractAddPathTest.configurePeer(this.tableRegistry, neighbor.getIpv4Address(), ribImpl,
+                null, PeerRole.Ibgp, this.serverRegistry, AFI_SAFIS_ADVERTIZED, Collections.emptySet());
         bgpPeer.instantiateServiceInstance();
         final BGPSessionImpl bgpSession = new BGPSessionImpl(bgpPeer, this.speakerListener, this.classicOpen,
                 this.classicOpen.getHoldTimer(), null);
index 8515650a4511d0c0526c00080ceae000cc39ab7f..f1abfdcaf8a07363ab6f480fd34932c0840b8506 100644 (file)
@@ -42,6 +42,7 @@ import org.opendaylight.protocol.bgp.mode.impl.add.all.paths.AllPathSelection;
 import org.opendaylight.protocol.bgp.mode.impl.add.n.paths.AddPathBestNPathSelection;
 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
+import org.opendaylight.protocol.bgp.parser.spi.pojo.RevisedErrorHandlingSupportImpl;
 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
@@ -50,6 +51,7 @@ import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.g
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.AfiSafis;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.AfiSafisBuilder;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ConfigBuilder;
+import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ErrorHandlingBuilder;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.RouteReflectorBuilder;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TimersBuilder;
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Transport;
@@ -489,4 +491,45 @@ public class OpenConfigMappingUtilTest {
                 .setRestartTime(restartTimer)
                 .build();
     }
+
+    @Test
+    public void getRevisedErrorHandlingTest() {
+        final NeighborBuilder neighbor = new NeighborBuilder();
+        final PeerGroupBuilder peerGroup = new PeerGroupBuilder();
+        final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.error.handling.ConfigBuilder errorHandlingConfig =
+                new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.error.handling.ConfigBuilder();
+        // error handling not set -> null
+        assertNull(OpenConfigMappingUtil.getRevisedErrorHandling(PeerRole.Ibgp, peerGroup.build(),
+                neighbor.build()));
+        // error handling for peer group disabled, neighbor not set -> null
+        peerGroup.setErrorHandling(new ErrorHandlingBuilder()
+                .setConfig(errorHandlingConfig.setTreatAsWithdraw(false).build())
+                .build());
+        assertNull(OpenConfigMappingUtil.getRevisedErrorHandling(PeerRole.Ibgp, peerGroup.build(),
+                neighbor.build()));
+        // error handling for peer group enabled, neighbor not set, Igp -> error handling for internal peer
+        peerGroup.setErrorHandling(new ErrorHandlingBuilder()
+                .setConfig(errorHandlingConfig.setTreatAsWithdraw(true).build())
+                .build());
+        assertEquals(RevisedErrorHandlingSupportImpl.forInternalPeer(),
+                OpenConfigMappingUtil.getRevisedErrorHandling(PeerRole.Ibgp, peerGroup.build(), neighbor.build()));
+        // error handling for peer group enabled, neighbor disabled -> null
+        neighbor.setErrorHandling(new ErrorHandlingBuilder()
+                .setConfig(errorHandlingConfig.setTreatAsWithdraw(false).build())
+                .build());
+        assertNull(OpenConfigMappingUtil.getRevisedErrorHandling(PeerRole.Ibgp, peerGroup.build(),
+                neighbor.build()));
+        // error handling for peer group enabled, neighbor enabled, Igb -> error handling for internal peer
+        neighbor.setErrorHandling(new ErrorHandlingBuilder()
+                .setConfig(errorHandlingConfig.setTreatAsWithdraw(true).build())
+                .build());
+        assertEquals(RevisedErrorHandlingSupportImpl.forInternalPeer(),
+                OpenConfigMappingUtil.getRevisedErrorHandling(PeerRole.Ibgp, peerGroup.build(), neighbor.build()));
+        // error handling for peer group enabled, neighbor enabled, Egb -> error handling for external peer
+        neighbor.setErrorHandling(new ErrorHandlingBuilder()
+                .setConfig(errorHandlingConfig.setTreatAsWithdraw(true).build())
+                .build());
+        assertEquals(RevisedErrorHandlingSupportImpl.forExternalPeer(),
+                OpenConfigMappingUtil.getRevisedErrorHandling(PeerRole.Ebgp, peerGroup.build(), neighbor.build()));
+    }
 }
\ No newline at end of file
index 31f34d0e2da4081846d7d683b14dad2a5974d1d4..6450118daa68d7a28f7bae2aa9abe0703ed549fa 100644 (file)
@@ -18,6 +18,7 @@ import java.util.Set;
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
+import org.opendaylight.protocol.bgp.parser.spi.PeerConstraint;
 import org.opendaylight.protocol.bgp.rib.spi.BGPSession;
 import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
 import org.opendaylight.protocol.bgp.rib.spi.BGPTerminationReason;
@@ -199,5 +200,11 @@ final class EventBusRegistration extends AbstractListenerRegistration<BGPSession
         public void closeWithoutMessage() {
             close();
         }
+
+        @Override
+        public <T extends PeerConstraint> void addDecoderConstraint(final Class<T> constraintClass,
+                final T constraint) {
+            // No-op
+        }
     }
 }
index 50f967d50df2819917e14f19f5ef09269424b4fe..1d4861e2073f132fc423e52935dcd40c20711699 100644 (file)
@@ -12,6 +12,7 @@ import java.util.List;
 import java.util.Set;
 import javax.annotation.Nonnull;
 import org.opendaylight.protocol.bgp.parser.GracefulRestartUtil;
+import org.opendaylight.protocol.bgp.parser.spi.PeerConstraint;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
@@ -84,4 +85,9 @@ public interface BGPSession extends AutoCloseable, ChannelInboundHandler {
      * Close peer session without sending Notification message.
      */
     void closeWithoutMessage();
+
+    /**
+     * Add peer constraint to session pipeline decoder.
+     */
+    <T extends PeerConstraint> void addDecoderConstraint(Class<T> constraintClass, T constraint);
 }