Add Exclude and Include Route for Path Computation 47/100247/4
authorOlivier Dugeon <olivier.dugeon@orange.com>
Thu, 24 Mar 2022 17:53:16 +0000 (18:53 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 30 Mar 2022 18:52:22 +0000 (20:52 +0200)
Exclude Route Object (XRO) and Include Route Object (IRO) are
part of RFC5440. Both objects have for goal to add constraints
on path computation: XRO to exclude some nodes or links and
IRO to force inclusion of them i.e. force some points for the
path description.

This new patch enhance the path-computation.yang model as well
as Path Computation algorithms to support both Exclude and
Include routes. If Exclude Route could be express without any
specific order, Include Route must be an ordered list of point:
i.e. to through A, then B and C, list should be <A, B, C> and
not <C, A, B> or other order.

Change-Id: I254086146ed03c8591d54bce3f7c527372ac9134
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
19 files changed:
algo/algo-api/src/main/java/org/opendaylight/algo/PathComputationAlgorithm.java
algo/algo-api/src/main/java/org/opendaylight/algo/PathComputationProvider.java
algo/algo-api/src/main/yang/path-computation.yang
algo/algo-impl/src/main/java/org/opendaylight/algo/impl/AbstractPathComputation.java
algo/algo-impl/src/main/java/org/opendaylight/algo/impl/ConstrainedShortestPathFirst.java
algo/algo-impl/src/main/java/org/opendaylight/algo/impl/PathComputationServer.java
algo/algo-impl/src/main/java/org/opendaylight/algo/impl/Samcra.java
algo/algo-impl/src/main/java/org/opendaylight/algo/impl/ShortestPathFirst.java
docs/algo/algo-user-guide-running-algo.rst
docs/pcep/pcep-user-guide-pce-server.rst
pcep/server/server-api/pom.xml
pcep/server/server-api/src/main/java/org/opendaylight/bgpcep/pcep/server/PathComputation.java
pcep/server/server-api/src/main/yang/pcep-server.yang
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/ManagedTePath.java
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/MessagesUtil.java
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PathComputationImpl.java
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PathManagerProvider.java
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PcepTopologyListener.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologySessionListener.java

index d325c3beeab4664a5b7d4a1c57b34d852d61eb37..97ac2b55b3d3c03ce483530e75fd96fc45e90c53 100644 (file)
@@ -10,8 +10,8 @@ package org.opendaylight.algo;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.PathConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ConstrainedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.PathConstraints;
 
 /**
  * This class provides entry for various Path Computation Algorithms.
index 6c48a4d4aae040de00e220aea526e85c8821250e..1c97b15068a2713a45d1e8ebc2bc940587823597 100644 (file)
@@ -9,7 +9,7 @@
 package org.opendaylight.algo;
 
 import org.opendaylight.graph.ConnectedGraph;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.AlgorithmType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.AlgorithmType;
 
 /**
  * This class provides access to Path Computation Algorithms.
index db076e8b0f35933043135b5a873dfb0e5eb18caa..36ea34b02ec711de1ca51f7d4b0811c77def0cc9 100644 (file)
@@ -3,7 +3,6 @@ module path-computation {
     namespace "urn:opendaylight:params:xml:ns:yang:path:computation";
     prefix "algo";
 
-    import network-concepts { prefix netc; revision-date 2013-11-25; }
     import ietf-inet-types { prefix inet; revision-date 2013-07-15; }
     import graph { prefix gr; revision-date 2019-11-25; }
 
@@ -21,6 +20,12 @@ module path-computation {
         accompanies this distribution, and is available at
         http://www.eclipse.org/legal/epl-v10.html";
 
+    revision "2022-03-24" {
+        description
+             "add Exclude Route and Include Route to constraints";
+        reference "";
+    }
+
     revision "2022-03-10" {
         description
              "add new computation status for failures and a type for address-family";
@@ -35,7 +40,7 @@ module path-computation {
 
     typedef computation-status {
         description
-            "Status of the Path Computation Algorithm regaring current
+            "Status of the Path Computation Algorithm regarding current
              computed path";
         type enumeration {
             enum idle {
@@ -162,6 +167,28 @@ module path-computation {
             description "Requested bandwidth for the computed path";
             type gr:decimal-bandwidth;
         }
+        list include-route {
+            description "Speficy routes which must be included in the computed path, i.e. IRO";
+            leaf ipv4 {
+                when "../../address-family = 0 or ../../address-family = 2";
+                type inet:ipv4-address;
+            }
+            leaf ipv6 {
+                when "../../address-family = 1 or ../../address-family = 3";
+                type inet:ipv6-address;
+            }
+        }
+        list exclude-route {
+            description "Speficy routes which must be excluded in the computed path, i.e. XRO";
+            leaf ipv4 {
+                when "../../address-family = 0 or ../../address-family = 2";
+                type inet:ipv4-address;
+            }
+            leaf ipv6 {
+                when "../../address-family = 1 or ../../address-family = 3";
+                type inet:ipv6-address;
+            }
+        }
     }
 
     grouping path-descriptions {
index 16190a2e846b36b47793dfae2786d2837e78becb..21dad91773988179120c9d067a222f787a708466 100644 (file)
@@ -16,17 +16,23 @@ import org.opendaylight.algo.PathComputationAlgorithm;
 import org.opendaylight.graph.ConnectedEdge;
 import org.opendaylight.graph.ConnectedGraph;
 import org.opendaylight.graph.ConnectedVertex;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.EdgeAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.UnreservedBandwidth;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Prefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.MplsLabel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ComputationStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPathBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.PathConstraints;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.path.descriptions.PathDescription;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.path.descriptions.PathDescriptionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ComputationStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ConstrainedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ConstrainedPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.PathConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.path.constraints.ExcludeRoute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.path.constraints.IncludeRoute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.path.descriptions.PathDescription;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.path.descriptions.PathDescriptionBuilder;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -109,44 +115,17 @@ public abstract class AbstractPathComputation implements PathComputationAlgorith
         return cpathBuilder;
     }
 
-    /**
-     * Check if Edge need to be prune regarding all constraints including
-     * address family.
-     *
-     * @return True if Edge must be prune, False if Edge must be keep
-     */
-    protected boolean pruneEdge(final ConnectedEdge edge, final CspfPath path) {
-        /* Check that Constraints are initialized */
-        if (constraints == null) {
-            LOG.warn("Constraints not set");
-            return true;
-        }
-
-        /* Edge could point to an unknown Vertex e.g. with inter-domain link */
-        if (edge.getDestination() == null || edge.getDestination().getVertex() == null) {
-            LOG.debug("No Destination");
-            return true;
-        }
-
-        /* Check that Edge have attributes */
-        EdgeAttributes attributes = edge.getEdge() != null ? edge.getEdge().getEdgeAttributes() : null;
-        if (attributes == null) {
-            LOG.debug("No attributes");
-            return true;
-        }
-
-        /* Check that Edge belongs to the requested address family */
+    private boolean verifyAddressFamily(final ConnectedEdge edge, final EdgeAttributes attributes) {
+        /* Check that Edge belongs to the Address Family of the requested path */
         switch (constraints.getAddressFamily()) {
             case Ipv4:
-                if (attributes.getRemoteAddress() == null
-                        || attributes.getRemoteAddress().getIpv4Address() == null) {
+                if (attributes.getRemoteAddress() == null || attributes.getRemoteAddress().getIpv4Address() == null) {
                     LOG.debug("No Ipv4 address");
                     return true;
                 }
                 break;
             case Ipv6:
-                if (attributes.getRemoteAddress() == null
-                        || attributes.getRemoteAddress().getIpv6Address() == null) {
+                if (attributes.getRemoteAddress() == null || attributes.getRemoteAddress().getIpv6Address() == null) {
                     LOG.debug("No Ipv6 address");
                     return true;
                 }
@@ -175,16 +154,11 @@ public abstract class AbstractPathComputation implements PathComputationAlgorith
                 return true;
         }
 
-        /* Skip checking other Constraints for simple SPF algorithm */
-        if (this instanceof ShortestPathFirst) {
-            LOG.trace("Edge {} is valid for Simple Path Computation", edge);
-            return false;
-        }
+        return false;
+    }
 
-        /*
-         * If specified, check that total TE Metric up to this edge respects the
-         * initial constraints
-         */
+    private boolean verifyMetrics(final EdgeAttributes attributes, final CspfPath path) {
+        /* If specified, check that total TE Metric up to this edge respects the initial constraints */
         if (constraints.getTeMetric() != null) {
             if (attributes.getTeMetric() == null) {
                 return true;
@@ -197,10 +171,7 @@ public abstract class AbstractPathComputation implements PathComputationAlgorith
             }
         }
 
-        /*
-         * If specified, check that total Delay up to this edge respects the
-         * initial constraints
-         */
+        /* If specified, check that total Delay up to this edge respects the initial constraints */
         if (constraints.getDelay() != null) {
             if (attributes.getDelay() == null) {
                 return true;
@@ -222,40 +193,138 @@ public abstract class AbstractPathComputation implements PathComputationAlgorith
             }
         }
 
-        /* Check that Edge meet Bandwidth constraint */
-        int cos = 0;
-        if (constraints.getClassType() != null) {
-            cos = constraints.getClassType().intValue();
-        }
-        if (constraints.getBandwidth() != null) {
-            if (attributes.getMaxLinkBandwidth() == null || attributes.getMaxResvLinkBandwidth() == null
-                    || attributes.getUnreservedBandwidth() == null
-                    || attributes.getUnreservedBandwidth().get(cos) == null) {
-                return true;
-            } else {
-                /* Get Unreserved Bandwidth for the given Class of Service / Priority */
-                Long bandwidth = constraints.getBandwidth().getValue().longValue();
-                Long unrsv = 0L;
-                for (UnreservedBandwidth unResBw : attributes.getUnreservedBandwidth()) {
-                    if (unResBw.getClassType().intValue() == cos) {
-                        unrsv = unResBw.getBandwidth().getValue().longValue();
-                        break;
+        return false;
+    }
+
+    private boolean verifyBandwidth(final ConnectedEdge edge, final EdgeAttributes attributes) {
+        if (constraints.getBandwidth() == null) {
+            return false;
+        }
+
+        int cos = constraints.getClassType() != null ? constraints.getClassType().intValue() : 0;
+        if (attributes.getMaxLinkBandwidth() == null
+                || attributes.getMaxResvLinkBandwidth() == null
+                || attributes.getUnreservedBandwidth() == null
+                || attributes.getUnreservedBandwidth().get(cos) == null) {
+            return true;
+        }
+
+        /* Get Unreserved Bandwidth for the given Class of Service / Priority */
+        Long bandwidth = constraints.getBandwidth().getValue().longValue();
+        Long unrsv = 0L;
+        for (UnreservedBandwidth unResBw : attributes.getUnreservedBandwidth()) {
+            if (unResBw.getClassType().intValue() == cos) {
+                unrsv = unResBw.getBandwidth().getValue().longValue();
+                break;
+            }
+        }
+        Long maxBW = attributes.getMaxLinkBandwidth().getValue().longValue();
+        if (bandwidth > List.of(unrsv,
+                // maxBW might be on the list but will always be greater
+                // than the next items
+                maxBW - edge.getCosResvBandwidth(cos), maxBW - edge.getGlobalResvBandwidth(),
+                attributes.getMaxResvLinkBandwidth().getValue().longValue()).stream().mapToLong(v -> v).min()
+                .getAsLong()) {
+            LOG.debug("Bandwidth constraint is not met");
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean verifyExcludeRoute(final ConnectedEdge edge, final EdgeAttributes attributes) {
+        if (constraints.getExcludeRoute() == null || constraints.getExcludeRoute().isEmpty()) {
+            return false;
+        }
+
+        final List<ExcludeRoute> xro = constraints.getExcludeRoute();
+        switch (constraints.getAddressFamily()) {
+            case Ipv4:
+            case SrIpv4:
+                for (int i = 0; i < xro.size(); i++) {
+                    final Ipv4Address address = xro.get(i).getIpv4();
+                    if (address.equals(attributes.getRemoteAddress().getIpv4Address())
+                            || address.equals(attributes.getLocalAddress().getIpv4Address())
+                            || address.equals(edge.getSource().getVertex().getRouterId().getIpv4Address())
+                            || address.equals(edge.getDestination().getVertex().getRouterId().getIpv4Address())) {
+                        return true;
                     }
                 }
-                Long maxBW = attributes.getMaxLinkBandwidth().getValue().longValue();
-                if (bandwidth > List.of(
-                            unrsv,
-                            // maxBW might be on the list but will always be greater than the next items
-                            maxBW - edge.getCosResvBandwidth(cos),
-                            maxBW - edge.getGlobalResvBandwidth(),
-                            attributes.getMaxResvLinkBandwidth().getValue().longValue())
-                        .stream().mapToLong(v -> v)
-                        .min().getAsLong()
-                ) {
-                    LOG.debug("Bandwidth constraint is not met");
+                break;
+            case Ipv6:
+            case SrIpv6:
+                for (int i = 0; i < xro.size(); i++) {
+                    final Ipv6Address address = xro.get(i).getIpv6();
+                    if (address.equals(attributes.getRemoteAddress().getIpv6Address())
+                            || address.equals(attributes.getLocalAddress().getIpv6Address())
+                            || address.equals(edge.getSource().getVertex().getRouterId().getIpv6Address())
+                            || address.equals(edge.getDestination().getVertex().getRouterId().getIpv6Address())) {
+                        return true;
+                    }
+                }
+                break;
+            default:
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Check if Edge need to be prune regarding all constraints including
+     * address family.
+     *
+     * @return True if Edge must be prune, False if Edge must be keep
+     */
+    protected boolean pruneEdge(final ConnectedEdge edge, final CspfPath path) {
+        /* Check that Constraints are initialized */
+        if (constraints == null) {
+            LOG.warn("Constraints not set");
+            return true;
+        }
+
+        /* Edge could point to an unknown Vertex e.g. with inter-domain link */
+        if (edge.getDestination() == null || edge.getDestination().getVertex() == null) {
+            LOG.debug("No Destination");
+            return true;
+        }
+
+        /* Check that Edge have attributes */
+        EdgeAttributes attributes = edge.getEdge() != null ? edge.getEdge().getEdgeAttributes() : null;
+        if (attributes == null) {
+            LOG.debug("No attributes");
+            return true;
+        }
+
+        /* Check that Edge belongs to the requested address family */
+        if (verifyAddressFamily(edge, attributes)) {
+            return true;
+        }
+
+        /* Check only IGP Metric, if specified, for simple SPF algorithm */
+        if (this instanceof ShortestPathFirst) {
+            if (constraints.getMetric() != null) {
+                if (attributes.getMetric() == null) {
+                    return true;
+                }
+                int totalCost = attributes.getMetric().intValue() + path.getCost();
+                if (totalCost > constraints.getMetric().intValue()) {
+                    LOG.debug("Metric {} exceed constraint {}", totalCost, constraints.getMetric().intValue());
                     return true;
                 }
             }
+            LOG.trace("Edge {} is valid for Simple Path Computation", edge);
+            return false;
+        }
+
+        /* Check that Edge respect Metric constraints */
+        if (verifyMetrics(attributes, path)) {
+            return true;
+        }
+
+        /* Check that Edge meet Bandwidth constraint */
+        if (verifyBandwidth(edge, attributes)) {
+            return true;
         }
 
         /* Check that Edge belongs to admin group */
@@ -265,6 +334,11 @@ public abstract class AbstractPathComputation implements PathComputationAlgorith
             return true;
         }
 
+        /* Check that Edge is not part of Exclude Route */
+        if (verifyExcludeRoute(edge, attributes)) {
+            return true;
+        }
+
         /*
          * OK. All is fine. We can consider this Edge valid, so not to be prune
          */
@@ -385,8 +459,64 @@ public abstract class AbstractPathComputation implements PathComputationAlgorith
         return list;
     }
 
+    private VertexKey getVertexKey(final IncludeRoute iro, AddressFamily af) {
+        IpAddress address = null;
+
+        switch (af) {
+            case Ipv4:
+            case SrIpv4:
+                address = new IpAddress(iro.getIpv4());
+                break;
+            case Ipv6:
+            case SrIpv6:
+                address = new IpAddress(iro.getIpv6());
+                break;
+            default:
+                return null;
+        }
+
+        ConnectedVertex vertex = graph.getConnectedVertex(address);
+        return vertex != null ? vertex.getVertex().key() : null;
+    }
+
+    private ConstrainedPath mergePath(ConstrainedPath cp1, ConstrainedPath cp2) {
+        ArrayList<PathDescription> mergePathDesc = new ArrayList<PathDescription>(cp1.getPathDescription());
+        mergePathDesc.addAll(cp2.getPathDescription());
+        return new ConstrainedPathBuilder(cp1)
+                .setPathDescription(mergePathDesc)
+                .setStatus(cp1.getStatus().equals(cp2.getStatus()) ? cp1.getStatus() : cp2.getStatus())
+                .build();
+    }
+
     @Override
-    public abstract ConstrainedPath computeP2pPath(VertexKey source, VertexKey destination,
-            PathConstraints constraints);
+    public ConstrainedPath computeP2pPath(VertexKey source, VertexKey destination, PathConstraints cts) {
+        this.constraints = cts;
+
+        if (constraints.getIncludeRoute() == null || constraints.getIncludeRoute().isEmpty()) {
+            return computeSimplePath(source, destination);
+        }
+
+        /* Start by computing Path from source to the first Include Route address */
+        VertexKey key = getVertexKey(constraints.getIncludeRoute().get(0), constraints.getAddressFamily());
+        ConstrainedPath ctsPath = computeSimplePath(source, key);
+        if (ctsPath.getStatus() != ComputationStatus.Completed) {
+            return ctsPath;
+        }
+
+        /* Then, loop other subsequent Include Route address */
+        for (int i = 1; i < constraints.getIncludeRoute().size() - 1; i++) {
+            VertexKey next = getVertexKey(constraints.getIncludeRoute().get(i), constraints.getAddressFamily());
+            ctsPath = mergePath(ctsPath, computeSimplePath(key, next));
+            if (ctsPath.getStatus() != ComputationStatus.Completed) {
+                return ctsPath;
+            }
+            key = next;
+        }
+
+        /* Finish path up to the destination */
+        return mergePath(ctsPath, computeSimplePath(key, destination));
+    }
+
+    protected abstract ConstrainedPath computeSimplePath(VertexKey source, VertexKey destination);
 
 }
index aab8be55e6e311bd1f63e72565d7407a5d48a9fe..3615aeb32c4bf5feed183267836990ecaaa24a0e 100644 (file)
@@ -12,10 +12,9 @@ import java.util.List;
 import org.opendaylight.graph.ConnectedEdge;
 import org.opendaylight.graph.ConnectedGraph;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ComputationStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPathBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.PathConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ComputationStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ConstrainedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ConstrainedPathBuilder;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,17 +37,15 @@ public class ConstrainedShortestPathFirst extends AbstractPathComputation {
     }
 
     @Override
-    public ConstrainedPath computeP2pPath(final VertexKey src, final VertexKey dst, final PathConstraints cts) {
-        LOG.info("Start CSPF Path Computation from {} to {} with constraints {}", src, dst, cts);
+    protected ConstrainedPath computeSimplePath(final VertexKey src, final VertexKey dst) {
+        LOG.info("Start CSPF Path Computation from {} to {} with constraints {}", src, dst, constraints);
 
         /* Initialize algorithm */
-        this.constraints = cts;
         ConstrainedPathBuilder cpathBuilder = initializePathComputation(src, dst);
         if (cpathBuilder.getStatus() != ComputationStatus.InProgress) {
             return cpathBuilder.build();
         }
-
-        cpathBuilder.setBandwidth(cts.getBandwidth()).setClassType(cts.getClassType());
+        cpathBuilder.setBandwidth(constraints.getBandwidth()).setClassType(constraints.getClassType());
 
         visitedVertices.clear();
 
index 8b89017eb6ccb86f3bbeec60756302a59bf46885..f54fc9b9ff2872f44b3cd5f1e66b52607012fd77 100644 (file)
@@ -19,13 +19,13 @@ import org.opendaylight.graph.ConnectedGraph;
 import org.opendaylight.graph.ConnectedGraphProvider;
 import org.opendaylight.mdsal.binding.api.RpcProviderService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.AlgorithmType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ComputationStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.GetConstrainedPathInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.GetConstrainedPathOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.GetConstrainedPathOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.PathComputationService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.AlgorithmType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ComputationStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ConstrainedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.GetConstrainedPathInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.GetConstrainedPathOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.GetConstrainedPathOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.PathComputationService;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.common.ErrorType;
 import org.opendaylight.yangtools.yang.common.RpcResult;
index 267556c48046c639cb45a00d6b49c5d7b8cca967..35ed348b45f938eed7cd503ab5d491c239d24037 100644 (file)
@@ -15,10 +15,9 @@ import org.opendaylight.graph.ConnectedGraph;
 import org.opendaylight.graph.ConnectedVertex;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Delay;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ComputationStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPathBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.PathConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ComputationStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ConstrainedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ConstrainedPathBuilder;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -123,16 +122,15 @@ public class Samcra extends AbstractPathComputation {
      */
 
     @Override
-    public ConstrainedPath computeP2pPath(final VertexKey src, final VertexKey dst, final PathConstraints cts) {
-        LOG.info("Start SAMCRA Path Computation from {} to {} with constraints {}", src, dst, cts);
+    protected ConstrainedPath computeSimplePath(final VertexKey src, final VertexKey dst) {
+        LOG.info("Start SAMCRA Path Computation from {} to {} with constraints {}", src, dst, constraints);
 
         /* Initialize SAMCRA variables */
-        this.constraints = cts;
         ConstrainedPathBuilder cpathBuilder = initializePathComputation(src, dst);
         if (cpathBuilder.getStatus() != ComputationStatus.InProgress) {
             return cpathBuilder.build();
         }
-        cpathBuilder.setBandwidth(cts.getBandwidth()).setClassType(cts.getClassType());
+        cpathBuilder.setBandwidth(constraints.getBandwidth()).setClassType(constraints.getClassType());
 
         samcraPaths.clear();
         samcraPaths.put(pathSource.getVertexKey(), new SamcraPath(pathSource.getVertex()));
index cb2da94daedb17869d8e8812081a9a745591196f..7a389883c9c884f70418eed9b8a008f03e0807f3 100644 (file)
@@ -12,10 +12,9 @@ import java.util.List;
 import org.opendaylight.graph.ConnectedEdge;
 import org.opendaylight.graph.ConnectedGraph;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ComputationStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPathBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.PathConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ComputationStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ConstrainedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ConstrainedPathBuilder;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -37,16 +36,15 @@ public class ShortestPathFirst extends AbstractPathComputation {
     }
 
     @Override
-    public ConstrainedPath computeP2pPath(final VertexKey src, final VertexKey dst, final PathConstraints cts) {
+    protected ConstrainedPath computeSimplePath(final VertexKey src, final VertexKey dst) {
         ConstrainedPathBuilder cpathBuilder;
         List<ConnectedEdge> edges;
         CspfPath currentPath;
         int currentCost = Integer.MAX_VALUE;
 
-        LOG.info("Start SPF Path Computation from {} to {} with constraints {}", src, dst, cts);
+        LOG.info("Start SPF Path Computation from {} to {} with constraints {}", src, dst, constraints);
 
         /* Initialize algorithm */
-        this.constraints = cts;
         cpathBuilder = initializePathComputation(src, dst);
         if (cpathBuilder.getStatus() != ComputationStatus.InProgress) {
             LOG.warn("Initial configurations are not met. Abort!");
index 36faa1fb35cf97bb388c9200db0571233f63195d..95ebb037a33eeb8fc9585ee19e6d8e397e0a7813 100644 (file)
@@ -33,7 +33,7 @@ The model is given below:
 
 .. code-block:: console
 
-      module: path-computation
+    module: path-computation
       +--rw constrained-path
          +--rw metric?             uint32
          +--rw te-metric?          uint32
@@ -41,44 +41,59 @@ The model is given below:
          +--rw jitter?             gr:delay
          +--rw loss?               gr:loss
          +--rw admin-group?        uint32
-         +--rw address-family?     enumeration
+         +--rw address-family?     address-family
          +--rw class-type?         uint8
          +--rw bandwidth?          gr:decimal-bandwidth
+         +--rw include-route* []
+         |  +--rw ipv4?   inet:ipv4-address
+         |  +--rw ipv6?   inet:ipv6-address
+         +--rw exclude-route* []
+         |  +--rw ipv4?   inet:ipv4-address
+         |  +--rw ipv6?   inet:ipv6-address
          +--rw source?             uint64
          +--rw destination?        uint64
          +--rw path-description* []
-         |  +--rw ipv4?    inet:ipv4-address
-         |  +--rw ipv6?    inet:ipv6-address
-         |  +--rw label?   netc:mpls-label
+         |  +--rw ipv4?          inet:ipv4-address
+         |  +--rw ipv6?          inet:ipv6-address
+         |  +--rw remote-ipv4?   inet:ipv4-address
+         |  +--rw remote-ipv6?   inet:ipv6-address
+         |  +--rw sid?           uint32
          +--rw status?             computation-status
 
       rpcs:
-         +---x get-constrained-path
-            +---w input
-            |  +---w graph-name     string
-            |  +---w source?        uint64
-            |  +---w destination?   uint64
-            |  +---w constraints
-            |  |  +---w metric?           uint32
-            |  |  +---w te-metric?        uint32
-            |  |  +---w delay?            gr:delay
-            |  |  +---w jitter?           gr:delay
-            |  |  +---w loss?             gr:loss
-            |  |  +---w admin-group?      uint32
-            |  |  +---w address-family?   enumeration
-            |  |  +---w class-type?       uint8
-            |  |  +---w bandwidth?        gr:decimal-bandwidth
-            |  +---w algorithm?     algorithm-type
-            +--ro output
-               +--ro path-description* []
-               |  +--ro ipv4?    inet:ipv4-address
-               |  +--ro ipv6?    inet:ipv6-address
-               |  +--ro label?   netc:mpls-label
-               +--ro status?               computation-status
-               +--ro computed-metric?      uint32
-               +--ro computed-te-metric?   uint32
-               +--ro computed-delay?       gr:delay
-
+        +---x get-constrained-path
+           +---w input
+           |  +---w graph-name     string
+           |  +---w source?        uint64
+           |  +---w destination?   uint64
+           |  +---w constraints
+           |  |  +---w metric?           uint32
+           |  |  +---w te-metric?        uint32
+           |  |  +---w delay?            gr:delay
+           |  |  +---w jitter?           gr:delay
+           |  |  +---w loss?             gr:loss
+           |  |  +---w admin-group?      uint32
+           |  |  +---w address-family?   address-family
+           |  |  +---w class-type?       uint8
+           |  |  +---w bandwidth?        gr:decimal-bandwidth
+           |  |  +---w include-route* []
+           |  |  |  +---w ipv4?   inet:ipv4-address
+           |  |  |  +---w ipv6?   inet:ipv6-address
+           |  |  +---w exclude-route* []
+           |  |     +---w ipv4?   inet:ipv4-address
+           |  |     +---w ipv6?   inet:ipv6-address
+           |  +---w algorithm?     algorithm-type
+           +--ro output
+              +--ro path-description* []
+              |  +--ro ipv4?          inet:ipv4-address
+              |  +--ro ipv6?          inet:ipv6-address
+              |  +--ro remote-ipv4?   inet:ipv4-address
+              |  +--ro remote-ipv6?   inet:ipv6-address
+              |  +--ro sid?           uint32
+              +--ro status?               computation-status
+              +--ro computed-metric?      uint32
+              +--ro computed-te-metric?   uint32
+              +--ro computed-delay?       gr:delay
 
 REST API
 ^^^^^^^^
@@ -149,13 +164,16 @@ are ``spf``, ``cspf`` and ``samcra`` - default ``spf``.
             "status": "completed",
             "path-description": [
                   {
-                     "ipv4": "10.194.77.143"
+                     "ipv4": "10.0.0.1",
+                     "remote-ipv4": "10.0.0.2"
                   },
                   {
-                     "ipv4": "10.194.77.155"
+                     "ipv4": "10.0.1.1",
+                     "remote-ipv4": "10.0.1.10"
                   },
                   {
-                     "ipv4": "10.194.77.161"
+                     "ipv4": "10.0.10.10",
+                     "remote-ipv4": "10.0.10.20"
                   }
             ]
          }
index 5949584a7477bbf7d36109a76c95eac4a4c5561f..155080a4872943546fc1e7b230b0d12f15a0b05a 100644 (file)
@@ -142,6 +142,12 @@ schema:
        |     +--ro address-family?   enumeration
        |     +--ro class-type?       uint8
        |     +--ro bandwidth?        gr:decimal-bandwidth
+       |     +--ro include-route* []
+       |     |  +--ro ipv4?   inet:ipv4-address
+       |     |  +--ro ipv6?   inet:ipv6-address
+       |     +--ro exclude-route* []
+       |        +--ro ipv4?   inet:ipv4-address
+       |        +--ro ipv6?   inet:ipv6-address
        +--ro computed-path
           +--ro path-description* []
           |  +--ro ipv4?          inet:ipv4-address
@@ -170,6 +176,12 @@ schema:
        |     +--rw address-family?   enumeration
        |     +--rw class-type?       uint8
        |     +--rw bandwidth?        gr:decimal-bandwidth
+       |     +--rw include-route* []
+       |     |  +--rw ipv4?   inet:ipv4-address
+       |     |  +--rw ipv6?   inet:ipv6-address
+       |     +--rw exclude-route* []
+       |        +--rw ipv4?   inet:ipv4-address
+       |        +--rw ipv6?   inet:ipv6-address
        +--ro computed-path
           +--ro path-description* []
           |  +--ro ipv4?          inet:ipv4-address
@@ -364,6 +376,17 @@ using the ``DELETE`` method as follow:
 
 **Method:** ``DELETE``
 
+Close Loop
+^^^^^^^^^^
+
+Each Managed TE Path automatically registers its current path within the
+Connected Graph whih serves to compute the route. In case of failure (Link or
+Node removal) or Link or Node attributes modifications in the Graph, registered
+Managed TE Path are trigger against those modifications. This feature allows
+the Path Manager to automatically detects problems in the underlying network
+topology and made appropriate action (i.e. mostly path re-computation and new
+computed path enforcement) in order to ensure that the constraints of the
+Managed TE Path are always guaranteed.
 
 Known limitations
 ^^^^^^^^^^^^^^^^^
@@ -374,8 +397,6 @@ mentioned hereinafter:
 * Following PCEP Objects that may be present in the PcRequest message are not
   yet supported, and right now, ignored:
 
-  * Include Route Object (IRO)
-  * Exclude Route Object (XRO)
   * Objective Function (OF)
 
 * For Segment Routing, ERO is only provided with Adjacency NAI type and Adjacency SID.
index 641273dcd38b8e8c7810c1f0462f8f34e685caab..e581379fc237c8aabdcca46c0794906e31b6eaf7 100644 (file)
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
-            <artifactId>pcep-ietf-stateful</artifactId>
+            <artifactId>pcep-topology-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>pcep-topology-api</artifactId>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>yang-ext</artifactId>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
index f4f9cfd662fe54bbc21137d07447f26b84eaf947..3fad9e879122d0349c2a26b2225408bde5c06739 100644 (file)
@@ -13,7 +13,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bandwidth.object.Bandwidth;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.classtype.object.ClassType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.object.EndpointsObj;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.exclude.route.object.Xro;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.include.route.object.Iro;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.Metrics;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.Requests;
 
@@ -22,5 +24,5 @@ public interface PathComputation {
     Message computePath(Requests req);
 
     Ero computeEro(EndpointsObj endpoints, Bandwidth bandwidth, ClassType classType, List<Metrics> metrics,
-            boolean segmentRouting);
+            Xro xro, Iro iro, boolean segmentRouting);
 }
index 9287b49d0909d4611dee12e4cb138905b8bd48df..74101f1ca305c01488002a98ae75215931c83e4a 100644 (file)
@@ -5,7 +5,7 @@ module pcep-server {
 
     import network-topology { prefix nt; revision-date 2013-10-21; }
     import ietf-inet-types { prefix inet; revision-date 2013-07-15; }
-    import path-computation { prefix algo; revision-date 2022-03-10; }
+    import path-computation { prefix algo; revision-date 2022-03-24; }
     import network-topology-pcep { prefix topo; revision-date 2020-01-20; }
     import yang-ext { prefix ext; revision-date 2013-07-09; }
 
index 96e3c6abb8a93272e69ca532f9e1d9005aca74c5..68e0465b55e3826b8bc8779105ba395c8a528e21 100644 (file)
@@ -36,9 +36,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.re
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ieee754.rev130819.Float32;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Bandwidth;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.topology.rev140113.NetworkTopologyRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ComputationStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.path.descriptions.PathDescription;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ComputationStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.path.descriptions.PathDescription;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.Arguments2Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.Arguments3Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.lsp.object.LspBuilder;
index 82dde529ceab80dc68a6b1527075abbf0554e2bc..3edb2f94b5a60d3a9b07d0931d993a2c53df4360 100644 (file)
@@ -21,8 +21,8 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ieee754.rev130819.Float32;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Bandwidth;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.path.descriptions.PathDescription;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ConstrainedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.path.descriptions.PathDescription;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcerr;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.PcerrBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcrep;
index 14041d593010624e0e3051a83dfa1dff6d876fd8..b60136f468a7ba30fcf138f8fad49c51705d1d2f 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.bgpcep.pcep.server.provider;
 import static java.util.Objects.requireNonNull;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.List;
 import org.opendaylight.algo.PathComputationAlgorithm;
 import org.opendaylight.algo.PathComputationProvider;
@@ -19,15 +20,21 @@ import org.opendaylight.graph.ConnectedVertex;
 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
 import org.opendaylight.protocol.pcep.spi.PSTUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.DecimalBandwidth;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Delay;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.AlgorithmType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ComputationStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ConstrainedPath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.PathConstraints;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.get.constrained.path.input.ConstraintsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.AlgorithmType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ComputationStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ConstrainedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.PathConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.get.constrained.path.input.ConstraintsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.path.constraints.ExcludeRoute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.path.constraints.ExcludeRouteBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.path.constraints.IncludeRoute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.path.constraints.IncludeRouteBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.ComputedPath;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.ComputedPathBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.pcc.configured.lsp.configured.lsp.IntendedPath;
@@ -37,10 +44,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.Ipv4Case;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.Ipv6Case;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.object.EndpointsObj;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.exclude.route.object.Xro;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.include.route.object.Iro;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.Metrics;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.Requests;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.P2p;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.SubobjectType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCase;
 import org.opendaylight.yangtools.yang.common.Decimal64;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.slf4j.Logger;
@@ -171,7 +182,7 @@ public class PathComputationImpl implements PathComputation {
 
     @Override
     public Ero computeEro(final EndpointsObj endpoints, final Bandwidth bandwidth, final ClassType classType,
-            final List<Metrics> metrics, final boolean segmentRouting) {
+            final List<Metrics> metrics, final Xro xro, final Iro iro, final boolean segmentRouting) {
         /* Get source and destination Vertex and verify there are valid */
         VertexKey source = getSourceVertexKey(endpoints);
         if (source == null) {
@@ -182,7 +193,7 @@ public class PathComputationImpl implements PathComputation {
             return null;
         }
         /* Create new Constraints Object from the request */
-        PathConstraints cts = getConstraints(endpoints, bandwidth, classType, metrics, segmentRouting);
+        PathConstraints cts = getConstraints(endpoints, bandwidth, classType, metrics, xro, iro, segmentRouting);
 
         /* Determine Path Computation Algorithm according to parameters */
         AlgorithmType algoType;
@@ -250,13 +261,76 @@ public class PathComputationImpl implements PathComputation {
         return vertex != null ? vertex.getVertex().key() : null;
     }
 
+    /* Convert Exclude Route Object (list of IP prefix) into Exclude Route (list of IP address) */
+    private static List<ExcludeRoute> getExcludeRoute(final Xro xro, AddressFamily af) {
+        if (xro == null || xro.getSubobject() == null || xro.getSubobject().isEmpty()) {
+            return null;
+        }
+        ArrayList<ExcludeRoute> erl = new ArrayList<ExcludeRoute>();
+        for (int i = 0; i < xro.getSubobject().size(); i++) {
+            final SubobjectType sbt = xro.getSubobject().get(i).getSubobjectType();
+            if (sbt instanceof IpPrefixCase) {
+                final IpPrefixCase ipc = (IpPrefixCase) sbt;
+                switch (af) {
+                    case Ipv4:
+                    case SrIpv4:
+                        erl.add(new ExcludeRouteBuilder().setIpv4(new Ipv4Address(
+                                ipc.getIpPrefix().getIpPrefix().getIpv4Prefix().getValue().split("/")[0]))
+                                .build());
+                        break;
+                    case Ipv6:
+                    case SrIpv6:
+                        erl.add(new ExcludeRouteBuilder().setIpv6(new Ipv6Address(
+                                ipc.getIpPrefix().getIpPrefix().getIpv6Prefix().getValue().split("/")[0]))
+                                .build());
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+        return erl;
+    }
+
+    /* Convert Include Route Object (list of IP prefix) into Exclude Route (list of IP address) */
+    private static List<IncludeRoute> getIncludeRoute(final Iro iro, AddressFamily af) {
+        if (iro == null || iro.getSubobject() == null || iro.getSubobject().isEmpty()) {
+            return null;
+        }
+        ArrayList<IncludeRoute> irl = new ArrayList<IncludeRoute>();
+        for (int i = 0; i < iro.getSubobject().size(); i++) {
+            final SubobjectType sbt = iro.getSubobject().get(i).getSubobjectType();
+            if (sbt instanceof IpPrefixCase) {
+                final IpPrefixCase ipc = (IpPrefixCase) sbt;
+                switch (af) {
+                    case Ipv4:
+                    case SrIpv4:
+                        irl.add(new IncludeRouteBuilder().setIpv4(new Ipv4Address(
+                                ipc.getIpPrefix().getIpPrefix().getIpv4Prefix().getValue().split("/")[0]))
+                                .build());
+                        break;
+                    case Ipv6:
+                    case SrIpv6:
+                        irl.add(new IncludeRouteBuilder().setIpv6(new Ipv6Address(
+                                ipc.getIpPrefix().getIpPrefix().getIpv6Prefix().getValue().split("/")[0]))
+                                .build());
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+        return irl;
+    }
+
     private static PathConstraints getConstraints(final P2p parameters, final boolean segmentRouting) {
         return getConstraints(parameters.getEndpointsObj(), parameters.getBandwidth(), parameters.getClassType(),
-                parameters.getMetrics(), segmentRouting);
+                parameters.getMetrics(), parameters.getXro(), parameters.getIro(), segmentRouting);
     }
 
     private static PathConstraints getConstraints(final EndpointsObj endpoints, final Bandwidth bandwidth,
-            final ClassType classType, final List<Metrics> metrics, final boolean segmentRouting) {
+            final ClassType classType, final List<Metrics> metrics, final Xro xro, final Iro iro,
+            final boolean segmentRouting) {
         ConstraintsBuilder ctsBuilder = new ConstraintsBuilder();
 
         /* Set Metrics if any */
@@ -300,13 +374,15 @@ public class PathComputationImpl implements PathComputation {
             }
         }
 
-        /* Set Address Family */
-        if (endpoints.getAddressFamily() instanceof Ipv4Case) {
-            ctsBuilder.setAddressFamily(segmentRouting ? AddressFamily.SrIpv4 : AddressFamily.Ipv4);
-        } else {
-            ctsBuilder.setAddressFamily(segmentRouting ? AddressFamily.SrIpv6 : AddressFamily.Ipv6);
-        }
+        AddressFamily af = endpoints.getAddressFamily() instanceof Ipv4Case
+                ? segmentRouting ? AddressFamily.SrIpv4 : AddressFamily.Ipv4
+                : segmentRouting ? AddressFamily.SrIpv6 : AddressFamily.Ipv6;
 
-        return ctsBuilder.build();
+        /* Set Address Family, Exclude Route and Include Route if any */
+        return ctsBuilder
+                .setAddressFamily(af)
+                .setExcludeRoute(getExcludeRoute(xro, af))
+                .setIncludeRoute(getIncludeRoute(iro, af))
+                .build();
     }
 }
index a22fcc598da311a50e7529a9f66677454dbf4313..876b9c8a8a72f9c705d88155139ff1132e38c4dc 100644 (file)
@@ -28,7 +28,7 @@ import org.opendaylight.mdsal.binding.api.TransactionChain;
 import org.opendaylight.mdsal.binding.api.TransactionChainListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Edge;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Vertex;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ComputationStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ComputationStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PathType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.server.rev220321.PcepNodeConfig;
index b7bdbc65a09f0dc608803a5115589dfa2bb1aa81..37c4deb684aa7fec49dceda868ca0e1d8e43d101 100644 (file)
@@ -26,10 +26,10 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.DecimalBandwidth;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Delay;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.ComputationStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.path.descriptions.PathDescription;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220310.path.descriptions.PathDescriptionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.ComputationStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.path.descriptions.PathDescription;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev220324.path.descriptions.PathDescriptionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.initiated.rev200720.Lsp1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.OperationalStatus;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.Path1;
index e1705076879979c2f966a56834b0146c4b7ab26b..2f8d6d262930d8b78eadaa1ddedad0db29ef34d3 100644 (file)
@@ -795,7 +795,7 @@ class PCEPTopologySessionListener extends AbstractTopologySessionListener<SrpIdN
                     return OperationResults.createUnsent(PCEPErrors.ERO_MISSING).future();
                 }
                 rb.setEro(pathComputation.computeEro(args.getEndpointsObj(), args.getBandwidth(),
-                        args.getClassType(), args.getMetrics(), segmentRouting));
+                        args.getClassType(), args.getMetrics(), args.getXro(), args.getIro(), segmentRouting));
             }
 
             final TlvsBuilder tlvsBuilder;