[CORD-575] Implements VPWS transport in SR app
Changes:
- Enables the BoS==False use case;
- Adds RandomNeighborSet to emulate the hashing;
Change-Id: I5cc05eb25f5185e612061880fcdb194ed71277d8
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
index d943710..f301a78 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
@@ -15,19 +15,8 @@
*/
package org.onosproject.segmentrouting.grouphandler;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
-
+import com.google.common.collect.Iterables;
+import org.apache.commons.lang3.RandomUtils;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
@@ -57,6 +46,19 @@
import org.onosproject.store.service.EventuallyConsistentMap;
import org.slf4j.Logger;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
/**
* Default ECMP group handler creation module. This component creates a set of
* ECMP groups for every neighbor that this device is connected to based on
@@ -427,10 +429,11 @@
*
* @param ns neighborset
* @param meta metadata passed into the creation of a Next Objective
+ * @param isBos if Bos is set
* @return int if found or -1 if there are errors in the creation of the
* neighbor set.
*/
- public int getNextObjectiveId(NeighborSet ns, TrafficSelector meta) {
+ public int getNextObjectiveId(NeighborSet ns, TrafficSelector meta, boolean isBos) {
Integer nextId = nsNextObjStore.
get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
if (nextId == null) {
@@ -443,7 +446,7 @@
.filter((nsStoreEntry) ->
(nsStoreEntry.getKey().deviceId().equals(deviceId)))
.collect(Collectors.toList()));
- createGroupsFromNeighborsets(Collections.singleton(ns), meta);
+ createGroupsFromNeighborsets(Collections.singleton(ns), meta, isBos);
nextId = nsNextObjStore.
get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
if (nextId == null) {
@@ -599,9 +602,7 @@
private boolean isSegmentIdSameAsNodeSegmentId(DeviceId deviceId, int sId) {
int segmentId;
try {
- /*
- * IPv6 sid is not inserted. this part of the code is not used for now.
- */
+ // IPv6 sid is not inserted. this part of the code is not used for now.
segmentId = deviceConfig.getIPv4SegmentId(deviceId);
} catch (DeviceConfigNotFoundException e) {
log.warn(e.getMessage() + " Aborting isSegmentIdSameAsNodeSegmentId.");
@@ -647,15 +648,28 @@
*
* @param nsSet a set of NeighborSet
* @param meta metadata passed into the creation of a Next Objective
+ * @param isBos if BoS is set
*/
public void createGroupsFromNeighborsets(Set<NeighborSet> nsSet,
- TrafficSelector meta) {
+ TrafficSelector meta,
+ boolean isBos) {
for (NeighborSet ns : nsSet) {
int nextId = flowObjectiveService.allocateNextId();
+ NextObjective.Type type = NextObjective.Type.HASHED;
+ Set<DeviceId> neighbors = ns.getDeviceIds();
+ // If Bos == False and MPLS-ECMP == false, we have
+ // to use simple group and we will pick a single neighbor.
+ if (!isBos && !srManager.getMplsEcmp()) {
+ type = NextObjective.Type.SIMPLE;
+ neighbors = Collections.singleton(ns.getFirstNeighbor());
+ }
NextObjective.Builder nextObjBuilder = DefaultNextObjective
- .builder().withId(nextId)
- .withType(NextObjective.Type.HASHED).fromApp(appId);
- for (DeviceId neighborId : ns.getDeviceIds()) {
+ .builder()
+ .withId(nextId)
+ .withType(type)
+ .fromApp(appId);
+ // For each neighbor, we have to update the sent actions
+ for (DeviceId neighborId : neighbors) {
if (devicePortMap.get(neighborId) == null) {
log.warn("Neighbor {} is not in the port map yet for dev:{}",
neighborId, deviceId);
@@ -673,8 +687,17 @@
log.warn(e.getMessage() + " Aborting createGroupsFromNeighborsets.");
return;
}
-
- for (PortNumber sp : devicePortMap.get(neighborId)) {
+ // For each port, we have to create a new treatment
+ Set<PortNumber> neighborPorts = devicePortMap.get(neighborId);
+ // In this case we are using a SIMPLE group. We randomly pick a port
+ if (!isBos && !srManager.getMplsEcmp()) {
+ int size = devicePortMap.get(neighborId).size();
+ int index = RandomUtils.nextInt(0, size);
+ neighborPorts = Collections.singleton(
+ Iterables.get(devicePortMap.get(neighborId), index)
+ );
+ }
+ for (PortNumber sp : neighborPorts) {
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
.builder();
tBuilder.setEthDst(neighborMac)
@@ -693,11 +716,13 @@
}
ObjectiveContext context = new DefaultObjectiveContext(
- (objective) -> log.debug("createGroupsFromNeighborsets installed NextObj {} on {}",
+ (objective) ->
+ log.debug("createGroupsFromNeighborsets installed NextObj {} on {}",
nextId, deviceId),
(objective, error) ->
log.warn("createGroupsFromNeighborsets failed to install NextObj {} on {}: {}",
- nextId, deviceId, error));
+ nextId, deviceId, error)
+ );
NextObjective nextObj = nextObjBuilder.add(context);
log.debug("**createGroupsFromNeighborsets: Submited "
+ "next objective {} in device {}",