[CORD-2486] Improve Mcast CLI APIs
It adds following commands:
- sr-mcast-tree which shows the mapping group-tree
- sr-mcast-next which shows the mapping device-next
- mcast-routes which is similar to the unicast command (routes)
It improve following commands:
- mcast-join adds completer and improves output
- mcast-delete adds completer and improves output
- mcast-show improves output and adds completer
Change-Id: I4e273ac23b05142026b6b77317b0c9b7af76c3ec
diff --git a/src/main/java/org/onosproject/segmentrouting/McastHandler.java b/src/main/java/org/onosproject/segmentrouting/McastHandler.java
index a5ef34c..fff2c92 100644
--- a/src/main/java/org/onosproject/segmentrouting/McastHandler.java
+++ b/src/main/java/org/onosproject/segmentrouting/McastHandler.java
@@ -1351,4 +1351,103 @@
}
}
+
+ public Map<McastStoreKey, Integer> getMcastNextIds(IpAddress mcastIp) {
+ // If mcast ip is present
+ if (mcastIp != null) {
+ return mcastNextObjStore.entrySet().stream()
+ .filter(mcastEntry -> mcastIp.equals(mcastEntry.getKey().mcastIp()))
+ .collect(Collectors.toMap(Map.Entry::getKey,
+ entry -> entry.getValue().value().id()));
+ }
+ // Otherwise take all the groups
+ return mcastNextObjStore.entrySet().stream()
+ .collect(Collectors.toMap(Map.Entry::getKey,
+ entry -> entry.getValue().value().id()));
+ }
+
+ public Map<McastStoreKey, McastHandler.McastRole> getMcastRoles(IpAddress mcastIp) {
+ // If mcast ip is present
+ if (mcastIp != null) {
+ return mcastRoleStore.entrySet().stream()
+ .filter(mcastEntry -> mcastIp.equals(mcastEntry.getKey().mcastIp()))
+ .collect(Collectors.toMap(Map.Entry::getKey,
+ entry -> entry.getValue().value()));
+ }
+ // Otherwise take all the groups
+ return mcastRoleStore.entrySet().stream()
+ .collect(Collectors.toMap(Map.Entry::getKey,
+ entry -> entry.getValue().value()));
+ }
+
+ public Map<ConnectPoint, List<ConnectPoint>> getMcastPaths(IpAddress mcastIp) {
+ Map<ConnectPoint, List<ConnectPoint>> mcastPaths = Maps.newHashMap();
+ // Get the source
+ ConnectPoint source = getSource(mcastIp);
+ // Source cannot be null, we don't know the starting point
+ if (source != null) {
+ // Init steps
+ Set<DeviceId> visited = Sets.newHashSet();
+ List<ConnectPoint> currentPath = Lists.newArrayList(
+ source
+ );
+ // Build recursively the mcast paths
+ buildMcastPaths(source.deviceId(), visited, mcastPaths, currentPath, mcastIp);
+ }
+ return mcastPaths;
+ }
+
+ private void buildMcastPaths(DeviceId toVisit, Set<DeviceId> visited,
+ Map<ConnectPoint, List<ConnectPoint>> mcastPaths,
+ List<ConnectPoint> currentPath, IpAddress mcastIp) {
+ // If we have visited the node to visit
+ // there is a loop
+ if (visited.contains(toVisit)) {
+ return;
+ }
+ // Visit next-hop
+ visited.add(toVisit);
+ McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, toVisit);
+ // Looking for next-hops
+ if (mcastNextObjStore.containsKey(mcastStoreKey)) {
+ // Build egress connectpoints
+ NextObjective nextObjective = mcastNextObjStore.get(mcastStoreKey).value();
+ // Get Ports
+ Set<PortNumber> outputPorts = getPorts(nextObjective.next());
+ // Build relative cps
+ ImmutableSet.Builder<ConnectPoint> cpBuilder = ImmutableSet.builder();
+ outputPorts.forEach(portNumber -> cpBuilder.add(new ConnectPoint(toVisit, portNumber)));
+ Set<ConnectPoint> egressPoints = cpBuilder.build();
+ // Define other variables for the next steps
+ Set<Link> egressLinks;
+ List<ConnectPoint> newCurrentPath;
+ Set<DeviceId> newVisited;
+ DeviceId newToVisit;
+ for (ConnectPoint egressPoint : egressPoints) {
+ egressLinks = srManager.linkService.getEgressLinks(egressPoint);
+ // If it does not have egress links, stop
+ if (egressLinks.isEmpty()) {
+ // Add the connect points to the path
+ newCurrentPath = Lists.newArrayList(currentPath);
+ newCurrentPath.add(0, egressPoint);
+ // Save in the map
+ mcastPaths.put(egressPoint, newCurrentPath);
+ } else {
+ newVisited = Sets.newHashSet(visited);
+ // Iterate over the egress links for the next hops
+ for (Link egressLink : egressLinks) {
+ // Update to visit
+ newToVisit = egressLink.dst().deviceId();
+ // Add the connect points to the path
+ newCurrentPath = Lists.newArrayList(currentPath);
+ newCurrentPath.add(0, egressPoint);
+ newCurrentPath.add(0, egressLink.dst());
+ // Go to the next hop
+ buildMcastPaths(newToVisit, newVisited, mcastPaths, newCurrentPath, mcastIp);
+ }
+ }
+ }
+ }
+ }
+
}