Add decoder constraint based on treat-as-withdrawn configuration
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / config / OpenConfigMappingUtil.java
index abea6acb9ecce77af40c67742489207c838cac1b..7190b1d63395cbbd061bf051cba360b43683a471 100644 (file)
@@ -25,7 +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.rib.spi.BGPPeerTracker;
+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 +35,8 @@ import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.r
 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.BgpNeighborAddPathsConfig;
 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;
@@ -59,14 +62,17 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.open
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborPeerGroupConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborTransportConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.PeerGroupTransportConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.TransportConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerRole;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.ClusterIdentifier;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-public final class OpenConfigMappingUtil {
+final class OpenConfigMappingUtil {
 
     static final String APPLICATION_PEER_GROUP_NAME = "application-peers";
+    static final Optional<String> APPLICATION_PEER_GROUP_NAME_OPT = Optional.of(APPLICATION_PEER_GROUP_NAME);
     static final int HOLDTIMER = 90;
     private static final AfiSafi IPV4_AFISAFI = new AfiSafiBuilder().setAfiSafiName(IPV4UNICAST.class).build();
     private static final List<AfiSafi> DEFAULT_AFISAFI = ImmutableList.of(IPV4_AFISAFI);
@@ -77,7 +83,7 @@ public final class OpenConfigMappingUtil {
         throw new UnsupportedOperationException();
     }
 
-    public static String getRibInstanceName(final InstanceIdentifier<?> rootIdentifier) {
+    static String getRibInstanceName(final InstanceIdentifier<?> rootIdentifier) {
         return rootIdentifier.firstKeyOf(Protocol.class).getName();
     }
 
@@ -130,7 +136,7 @@ public final class OpenConfigMappingUtil {
         return null;
     }
 
-    public static KeyMapping getNeighborKey(final Neighbor neighbor) {
+    static KeyMapping getNeighborKey(final Neighbor neighbor) {
         if (neighbor.getConfig() != null) {
             final String authPassword = neighbor.getConfig().getAuthPassword();
             if (authPassword != null) {
@@ -140,36 +146,33 @@ public final class OpenConfigMappingUtil {
         return null;
     }
 
-    public static InstanceIdentifier<Neighbor> getNeighborInstanceIdentifier(
+    static InstanceIdentifier<Neighbor> getNeighborInstanceIdentifier(
             final InstanceIdentifier<Bgp> rootIdentifier,
             final NeighborKey neighborKey) {
         return rootIdentifier.child(Neighbors.class).child(Neighbor.class, neighborKey);
     }
 
-    public static String getNeighborInstanceName(final InstanceIdentifier<?> rootIdentifier) {
+    static String getNeighborInstanceName(final InstanceIdentifier<?> rootIdentifier) {
         return Ipv4Util.toStringIP(rootIdentifier.firstKeyOf(Neighbor.class).getNeighborAddress());
     }
 
     @Nullable
-    private static PortNumber getPort(@Nullable final Transport transport) {
+    private static <T extends TransportConfig & Augmentation<Config>> PortNumber getPort(
+            @Nullable final Transport transport, final Class<T> augment) {
         if (transport != null) {
             final Config config = transport.getConfig();
             if (config != null) {
-                final NeighborTransportConfig peerTc = config.augmentation(NeighborTransportConfig.class);
+                final T peerTc = config.augmentation(augment);
                 if (peerTc != null) {
                     return peerTc.getRemotePort();
                 }
-                final PeerGroupTransportConfig peerGroupTc = config.augmentation(PeerGroupTransportConfig.class);
-                if (peerGroupTc != null) {
-                    return peerGroupTc.getRemotePort();
-                }
             }
         }
         return null;
     }
 
     //make sure IPv4 Unicast (RFC 4271) when required
-    public static List<AfiSafi> getAfiSafiWithDefault(
+    static List<AfiSafi> getAfiSafiWithDefault(
             final BgpCommonAfiSafiList afiSAfis, final boolean setDeafultIPv4) {
         if (afiSAfis == null || afiSAfis.getAfiSafi() == null) {
             return setDeafultIPv4 ? DEFAULT_AFISAFI : Collections.emptyList();
@@ -185,7 +188,7 @@ public final class OpenConfigMappingUtil {
         return afiSafi;
     }
 
-    public static ClusterIdentifier getGlobalClusterIdentifier(final org.opendaylight.yang.gen.v1.http.openconfig.net
+    static ClusterIdentifier getGlobalClusterIdentifier(final org.opendaylight.yang.gen.v1.http.openconfig.net
             .yang.bgp.rev151009.bgp.global.base.Config globalConfig) {
         final GlobalConfigAugmentation globalConfigAugmentation
                 = globalConfig.augmentation(GlobalConfigAugmentation.class);
@@ -196,7 +199,7 @@ public final class OpenConfigMappingUtil {
     }
 
     @Nullable
-    public static ClusterIdentifier getNeighborClusterIdentifier(
+    static ClusterIdentifier getNeighborClusterIdentifier(
             @Nullable final RouteReflector routeReflector,
             @Nullable final PeerGroup peerGroup) {
         if (peerGroup != null) {
@@ -220,7 +223,7 @@ public final class OpenConfigMappingUtil {
         return null;
     }
 
-    public static Map<BgpTableType, PathSelectionMode> toPathSelectionMode(final List<AfiSafi> afiSafis,
+    static Map<BgpTableType, PathSelectionMode> toPathSelectionMode(final List<AfiSafi> afiSafis,
             final BGPTableTypeRegistryConsumer tableTypeRegistry) {
         final Map<BgpTableType, PathSelectionMode> pathSelectionModes = new HashMap<>();
         for (final AfiSafi afiSafi : afiSafis) {
@@ -228,10 +231,10 @@ public final class OpenConfigMappingUtil {
             if (afiSafi2 != null) {
                 final Optional<BgpTableType> bgpTableType = tableTypeRegistry.getTableType(afiSafi.getAfiSafiName());
                 if (bgpTableType.isPresent()) {
-                    final Short sendMax = afiSafi2.getSendMax();
+                    final int sendMax = afiSafi2.getSendMax();
                     final PathSelectionMode selectionMode;
                     if (sendMax > 1) {
-                        selectionMode = new AddPathBestNPathSelection(sendMax.longValue());
+                        selectionMode = new AddPathBestNPathSelection(sendMax);
                     } else {
                         selectionMode = new AllPathSelection();
                     }
@@ -242,7 +245,7 @@ public final class OpenConfigMappingUtil {
         return pathSelectionModes;
     }
 
-    public static boolean isApplicationPeer(final Neighbor neighbor) {
+    static boolean isApplicationPeer(final Neighbor neighbor) {
         final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group
                 .Config config = neighbor.getConfig();
         if (config != null) {
@@ -255,7 +258,7 @@ public final class OpenConfigMappingUtil {
         return false;
     }
 
-    public static List<AddressFamilies> toAddPathCapability(final List<AfiSafi> afiSafis,
+    static List<AddressFamilies> toAddPathCapability(final List<AfiSafi> afiSafis,
             final BGPTableTypeRegistryConsumer tableTypeRegistry) {
         final List<AddressFamilies> addPathCapability = new ArrayList<>();
         for (final AfiSafi afiSafi : afiSafis) {
@@ -280,7 +283,7 @@ public final class OpenConfigMappingUtil {
         return SendReceive.Receive;
     }
 
-    public static PeerRole toPeerRole(final BgpNeighborGroup neighbor) {
+    static PeerRole toPeerRole(final BgpNeighborGroup neighbor) {
         if (isRrClient(neighbor)) {
             return PeerRole.RrClient;
         }
@@ -304,7 +307,7 @@ public final class OpenConfigMappingUtil {
         return false;
     }
 
-    public static List<BgpTableType> toTableTypes(final List<AfiSafi> afiSafis,
+    static List<BgpTableType> toTableTypes(final List<AfiSafi> afiSafis,
             final BGPTableTypeRegistryConsumer tableTypeRegistry) {
         return afiSafis.stream()
                 .map(afiSafi -> tableTypeRegistry.getTableType(afiSafi.getAfiSafiName()))
@@ -313,7 +316,7 @@ public final class OpenConfigMappingUtil {
                 .collect(Collectors.toList());
     }
 
-    public static Set<TablesKey> toTableKey(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer
+    static Set<TablesKey> toTableKey(final List<AfiSafi> afiSafis, final BGPTableTypeRegistryConsumer
             tableTypeRegistry) {
         return afiSafis.stream()
                 .map(afiSafi -> tableTypeRegistry.getTableKey(afiSafi.getAfiSafiName()))
@@ -322,8 +325,7 @@ public final class OpenConfigMappingUtil {
                 .collect(Collectors.toSet());
     }
 
-    @Nonnull
-    public static boolean isActive(final Neighbor neighbor, final PeerGroup peerGroup) {
+    static boolean isActive(final Neighbor neighbor, final PeerGroup peerGroup) {
         Boolean activeConnection = null;
         if (peerGroup != null) {
             activeConnection = isActive(peerGroup.getTransport());
@@ -339,7 +341,7 @@ public final class OpenConfigMappingUtil {
     }
 
     @Nonnull
-    public static PeerRole toPeerRole(final Neighbor neighbor, final PeerGroup peerGroup) {
+    static PeerRole toPeerRole(final Neighbor neighbor, final PeerGroup peerGroup) {
         PeerRole role = null;
         if (peerGroup != null) {
             role = toPeerRole(peerGroup);
@@ -355,7 +357,7 @@ public final class OpenConfigMappingUtil {
         return role;
     }
 
-    public static int getHoldTimer(final Neighbor neighbor, final PeerGroup peerGroup) {
+    static int getHoldTimer(final Neighbor neighbor, final PeerGroup peerGroup) {
         Integer hold = null;
         if (peerGroup != null) {
             hold = getHoldTimer(peerGroup.getTimers());
@@ -372,8 +374,41 @@ public final class OpenConfigMappingUtil {
         return hold;
     }
 
+    static int getGracefulRestartTimer(final Neighbor neighbor, final PeerGroup peerGroup, final int holdTimer) {
+        Integer timer = null;
+        if (peerGroup != null) {
+            timer = getGracefulRestartTimer(peerGroup.getGracefulRestart());
+        }
+
+        if (timer == null) {
+            timer = getGracefulRestartTimer(neighbor.getGracefulRestart());
+        }
+
+        /*
+         * RFC4724: "A suggested default for the Restart Time is a value less than or
+         * equal to the HOLDTIME carried in the OPEN."
+         */
+        if (timer == null) {
+            timer = holdTimer;
+        }
+
+        return timer;
+    }
+
+    @Nullable
+    private static Integer getGracefulRestartTimer(final GracefulRestart gracefulRestart) {
+        if (gracefulRestart != null) {
+            final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.graceful.restart.graceful
+                    .restart.Config config = gracefulRestart.getConfig();
+            if (config != null) {
+                return config.getRestartTime();
+            }
+        }
+        return null;
+    }
+
     @Nonnull
-    public static AsNumber getRemotePeerAs(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009
+    static AsNumber getRemotePeerAs(final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009
             .bgp.neighbor.group.Config config, final PeerGroup peerGroup, final AsNumber localAs) {
         AsNumber neighborAs = null;
         if (peerGroup != null) {
@@ -391,7 +426,7 @@ public final class OpenConfigMappingUtil {
     }
 
     @Nonnull
-    public static AsNumber getLocalPeerAs(@Nullable final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp
+    static AsNumber getLocalPeerAs(@Nullable final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp
             .rev151009.bgp.neighbor.group.Config config, @Nonnull final AsNumber globalAs) {
         if (config != null) {
             final AsNumber peerAs = config.getLocalAs();
@@ -402,7 +437,7 @@ public final class OpenConfigMappingUtil {
         return globalAs;
     }
 
-    public static int getRetryTimer(final Neighbor neighbor, final PeerGroup peerGroup) {
+    static int getRetryTimer(final Neighbor neighbor, final PeerGroup peerGroup) {
         Integer retryTimer = null;
         if (peerGroup != null) {
             retryTimer = getRetryTimer(peerGroup.getTimers());
@@ -420,14 +455,14 @@ public final class OpenConfigMappingUtil {
     }
 
     @Nonnull
-    public static PortNumber getPort(final Neighbor neighbor, final PeerGroup peerGroup) {
+    static PortNumber getPort(final Neighbor neighbor, final PeerGroup peerGroup) {
         PortNumber port = null;
         if (peerGroup != null) {
-            port = getPort(peerGroup.getTransport());
+            port = getPort(peerGroup.getTransport(), PeerGroupTransportConfig.class);
         }
 
         if (port == null) {
-            port = getPort(neighbor.getTransport());
+            port = getPort(neighbor.getTransport(), NeighborTransportConfig.class);
         }
 
         if (port == null) {
@@ -438,7 +473,7 @@ public final class OpenConfigMappingUtil {
     }
 
     @Nullable
-    public static IpAddress getLocalAddress(@Nullable final Transport transport) {
+    static IpAddress getLocalAddress(@Nullable final Transport transport) {
         if (transport != null && transport.getConfig() != null) {
             final BgpNeighborTransportConfig.LocalAddress localAddress = transport.getConfig().getLocalAddress();
             if (localAddress != null ) {
@@ -447,4 +482,40 @@ public 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();
+    }
 }