Use SRLinkWeigher in path computation.
This patch uses the SRLinkWeigher to compute paths in
order to avoid l-s-l-s paths and also paired leafs
paths.
Change-Id: Id532d66e9543e3c898d2e18ca53be4599e206935
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
index 47a73d4..eb18381 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
@@ -45,6 +45,8 @@
import org.onosproject.net.flowobjective.Objective;
import org.onosproject.net.flowobjective.ObjectiveContext;
import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.topology.LinkWeigher;
+import org.onosproject.segmentrouting.SRLinkWeigher;
import org.onosproject.segmentrouting.SegmentRoutingManager;
import org.onosproject.segmentrouting.SegmentRoutingService;
import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
@@ -57,6 +59,7 @@
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
@@ -569,6 +572,16 @@
.appendError("Device for pseudowire connection points does not exist in the configuration");
}
+ // reverse the policy in order for leaf switch to be at CP1
+ // this will help us for re-using SRLinkWeigher for computing valid paths
+ L2TunnelPolicy reversedPolicy = reverseL2TunnelPolicy(pw.l2TunnelPolicy());
+ if (reversedPolicy == null) {
+ log.error("Error in reversing policy, device configuration was not found!");
+ return INTERNAL_ERROR
+ .appendError("Device configuration not found when reversing the policy.");
+ }
+ pw.setL2TunnelPolicy(reversedPolicy);
+
// get path here, need to use the same for fwd and rev direction
List<Link> path = getPath(pw.l2TunnelPolicy().cP1(),
pw.l2TunnelPolicy().cP2());
@@ -1360,6 +1373,37 @@
}
/**
+ * Reverse an l2 tunnel policy in order to have as CP1 the leaf switch,
+ * in case one of the switches is a spine.
+ *
+ * This makes possible the usage of SRLinkWeigher for computing valid paths,
+ * which cuts leaf-spine links from the path computation with a src different
+ * than the source leaf.
+ *
+ * @param policy The policy to reverse, if needed
+ * @return a l2TunnelPolicy containing the leaf at CP1, suitable for usage with
+ * current SRLinkWeigher
+ */
+ private L2TunnelPolicy reverseL2TunnelPolicy(L2TunnelPolicy policy) {
+ try {
+ // if cp1 is a leaf, just return
+ if (srManager.deviceConfiguration().isEdgeDevice(policy.cP1().deviceId())) {
+ return policy;
+ } else {
+ // return a policy with reversed cp1 and cp2, and also with reversed tags
+ return new DefaultL2TunnelPolicy(policy.tunnelId(),
+ policy.cP2(), policy.cP2InnerTag(), policy.cP2OuterTag(),
+ policy.cP1(), policy.cP1InnerTag(), policy.cP1OuterTag());
+
+ }
+ } catch (DeviceConfigNotFoundException e) {
+ // should never come here, since it has been checked before
+ log.error("Configuration for device {}, does not exist!");
+ return null;
+ }
+ }
+
+ /**
* Reverses a link.
*
* @param link link to be reversed
@@ -1385,9 +1429,15 @@
* @return the path
*/
private List<Link> getPath(ConnectPoint srcCp, ConnectPoint dstCp) {
- Set<Path> paths = srManager.topologyService.getPaths(
- srManager.topologyService.currentTopology(),
- srcCp.deviceId(), dstCp.deviceId());
+
+ // use SRLinkWeigher to avoid pair links, and also
+ // avoid going from the spine to the leaf and to the
+ // spine again, we need to have the leaf as CP1 here.
+ LinkWeigher srLw = new SRLinkWeigher(srManager, srcCp.deviceId(), new HashSet<Link>());
+
+ Set<Path> paths = srManager.topologyService.
+ getPaths(srManager.topologyService.currentTopology(),
+ srcCp.deviceId(), dstCp.deviceId(), srLw);
log.debug("Paths obtained from topology service {}", paths);