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.
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.
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; }
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";
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 {
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 {
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;
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;
}
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;
}
}
- /*
- * 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;
}
}
- /* 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 */
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
*/
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);
}
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;
}
@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();
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;
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;
*/
@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()));
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;
}
@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!");
.. code-block:: console
- module: path-computation
+ module: path-computation
+--rw constrained-path
+--rw metric? uint32
+--rw te-metric? uint32
+--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
^^^^^^^^
"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"
}
]
}
| +--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
| +--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
**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
^^^^^^^^^^^^^^^^^
* 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.
</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>
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;
Message computePath(Requests req);
Ero computeEro(EndpointsObj endpoints, Bandwidth bandwidth, ClassType classType, List<Metrics> metrics,
- boolean segmentRouting);
+ Xro xro, Iro iro, boolean segmentRouting);
}
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; }
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;
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;
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;
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;
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;
@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) {
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;
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 */
}
}
- /* 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();
}
}
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;
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;
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;