Modify createGroup and removeGroup for tunnel to handle multiple instances
- createGroup() of the driver returns a list of group IDs
- removeGroup() removes only the group specified
- Application removes all the groups for the tunnel
diff --git a/src/main/java/net/floodlightcontroller/core/IOF13Switch.java b/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
index 1dbfc1c..04e2a8d 100644
--- a/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
+++ b/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
@@ -213,7 +213,7 @@
* the labelStack
* @return group identifier
*/
- public int createGroup(List<Integer> labelStack, List<PortNumber> ports);
+ public List<Integer> createGroup(List<Integer> labelStack, List<PortNumber> ports);
/**
* Remove the specified group
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
index 48903c9..d1f8966 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
@@ -350,7 +350,9 @@
@Override
public void entryRemoved(TunnelNotification tunnelNotification) {
- tunnelTable.remove(tunnelNotification.getTunnelId());
+ if (tunnelTable.containsKey(tunnelNotification.getTunnelId())) {
+ srManager.removeTunnel(tunnelNotification.getTunnelId());
+ }
}
@Override
@@ -822,26 +824,29 @@
if (adjGroupIdMap != null) {
groupId = adjGroupIdMap.get(key);
if (groupId == null) {
- groupId = sw13.createGroup(new ArrayList<Integer>(),
- portList);
- if (groupId < 0) {
+ List<Integer> groupIdList = sw13.createGroup(
+ new ArrayList<Integer>(), portList);
+ if (groupIdList == null || groupIdList.isEmpty()) {
log.debug("Failed to create a group at driver for "
+ "adj ID {}", adjId);
return;
}
else {
+ groupId = groupIdList.get(0);
adjGroupIdMap.put(key, groupId);
}
}
}
else {
- groupId = sw13.createGroup(new ArrayList<Integer>(), portList);
- if (groupId < 0) {
+ List<Integer> groupIdList = sw13.createGroup(
+ new ArrayList<Integer>(), portList);
+ if (groupIdList == null || groupIdList.isEmpty()) {
log.debug("Failed to create a group at driver for adj ID {}",
adjId);
return;
}
else {
+ groupId = groupIdList.get(0);
adjGroupIdMap = new HashMap<Integer, Integer>();
adjGroupIdMap.put(key, groupId);
adjcencyGroupIdTable.put(sw.getDpid().toString(),
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicy.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicy.java
index 86c0009..81b1870 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicy.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicy.java
@@ -8,7 +8,7 @@
* Enums for policy type
*
*/
- public enum PolicyType{
+ public enum PolicyType {
TUNNEL_FLOW,
LOADBALANCE,
AVOID,
@@ -52,7 +52,7 @@
*
* @return policy ID
*/
- public String getPolicyId(){
+ public String getPolicyId() {
return this.policyId;
}
@@ -61,7 +61,7 @@
*
* @return PacketMatch object
*/
- public PacketMatch getMatch(){
+ public PacketMatch getMatch() {
return this.match;
}
@@ -70,7 +70,7 @@
*
* @return priority
*/
- public int getPriority(){
+ public int getPriority() {
return this.priority;
}
@@ -79,7 +79,7 @@
*
* @return policy type
*/
- public PolicyType getType(){
+ public PolicyType getType() {
return this.type;
}
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingTunnel.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingTunnel.java
index ad5e0f1..a5a0f2b 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingTunnel.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingTunnel.java
@@ -41,30 +41,45 @@
this.routes = new ArrayList<TunnelRouteInfo>();
}
- public SegmentRoutingTunnel(SegmentRoutingManager srm, TunnelNotification tunnelNotification) {
+ /**
+ * Constructor
+ *
+ * @param srm SegmentRoutingManager objeect
+ * @param tunnelNotification tunnel information published by other controllers
+ */
+ public SegmentRoutingTunnel(SegmentRoutingManager srm,
+ TunnelNotification tunnelNotification) {
this.srManager = srm;
this.tunnelId = tunnelNotification.getTunnelId();
this.labelIds = tunnelNotification.getLabelIds();
this.routes = tunnelNotification.getRouteInfo();
}
+ /**
+ * Check if there is any sub tunnel that starts with the router managed by
+ * the controller. If so, create groups for the sub tunnel and set the
+ * group Id list. Then, set modified flag to true so that the tunnel
+ * information is published again with the new group ID list.
+ *
+ * @return true if any new group is created, otherwise false.
+ */
public boolean checkAndCreateTunnel() {
boolean modified = false;
for (TunnelRouteInfo route: routes) {
if (srManager.getIOF13Switch(route.getSrcSwDpid()) != null) {
- if (route.getGroupId() == -1) {
+ if (route.getGroupIdList() == null) {
NeighborSet ns = new NeighborSet();
for (Dpid dpid: route.getFwdSwDpid())
ns.addDpid(dpid);
printTunnelInfo(route.srcSwDpid, tunnelId, route.getRoute(), ns);
- int groupId = -1;
- if ((groupId =createGroupsForTunnel(tunnelId, route, ns)) < 0) {
+ List<Integer> groupIdList = createGroupsForTunnel(tunnelId, route, ns);
+ if (groupIdList == null) {
log.debug("Failed to create a tunnel at driver.");
return false;
}
- route.setGroupId(groupId);
+ route.setGroupIdList(groupIdList);
modified = true;
}
}
@@ -137,15 +152,15 @@
ns.addDpid(dpid);
printTunnelInfo(route.srcSwDpid, tunnelId, route.getRoute(), ns);
- int groupId = -1;
- if ((groupId =createGroupsForTunnel(tunnelId, route, ns)) < 0) {
+ List<Integer> groupIdList = null;
+ if ((groupIdList =createGroupsForTunnel(tunnelId, route, ns)) == null) {
log.debug("Failed to create a tunnel at driver.");
return false;
}
- route.setGroupId(groupId);
+ route.setGroupIdList(groupIdList);
}
else {
- route.setGroupId(-1);
+ route.setGroupIdList(null);
}
}
@@ -230,10 +245,15 @@
for (TunnelRouteInfo route: routes) {
IOF13Switch sw13 = srManager.getIOF13Switch(route.srcSwDpid);
if (sw13 != null) {
- if (!sw13.removeGroup(route.getGroupId())) {
- log.warn("Faied to remove the tunnel {} at driver",
- tunnelId);
- return false;
+ // Group needs to be removed in reverse order because
+ // the group being pointed by any other group cannot be removed
+ for (int i = route.getGroupIdList().size()-1; i >= 0; i--) {
+ int groupId = route.getGroupIdList().get(i);
+ if (!sw13.removeGroup(groupId)) {
+ log.warn("Faied to remove the tunnel {} at driver",
+ tunnelId);
+ return false;
+ }
}
}
}
@@ -249,14 +269,14 @@
* @param ns NeighborSet to forward packets
* @return group ID, return -1 if it fails
*/
- private int createGroupsForTunnel(String tunnelId, TunnelRouteInfo routeInfo,
+ private List<Integer> createGroupsForTunnel(String tunnelId, TunnelRouteInfo routeInfo,
NeighborSet ns) {
IOF13Switch targetSw = srManager.getIOF13Switch(routeInfo.srcSwDpid);
if (targetSw == null) {
log.debug("Switch {} is gone.", routeInfo.srcSwDpid);
- return -1;
+ return null;
}
List<Integer> Ids = new ArrayList<Integer>();
@@ -264,9 +284,9 @@
Ids.add(Integer.parseInt(IdStr));
List<PortNumber> ports = getPortsFromNeighborSet(routeInfo.srcSwDpid, ns);
- int groupId = targetSw.createGroup(Ids, ports);
+ List<Integer> groupIdList = targetSw.createGroup(Ids, ports);
- return groupId;
+ return groupIdList;
}
/**
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/TunnelRouteInfo.java b/src/main/java/net/onrc/onos/apps/segmentrouting/TunnelRouteInfo.java
index 8c63f84..19b94e7 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/TunnelRouteInfo.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/TunnelRouteInfo.java
@@ -10,7 +10,7 @@
public String srcSwDpid;
public List<Dpid> fwdSwDpids;
public List<String> route;
- public int gropuId;
+ public List<Integer> groupIdList;
/**
* Constructor
@@ -48,14 +48,12 @@
}
/**
- * Set the group ID for the sub tunnel
- * The group pushes all the IDs in label stack and forward to the next
- * router.
+ * Set the group ID list for the tunnel
*
- * @param groupId
+ * @param gidLIst List of group ID
*/
- public void setGroupId(int groupId) {
- this.gropuId = groupId;
+ public void setGroupIdList(List<Integer> gidLIst) {
+ this.groupIdList = gidLIst;
}
/**
@@ -91,6 +89,16 @@
* @return Group ID
*/
public int getGroupId() {
- return this.gropuId;
+ return groupIdList.get(groupIdList.size()-1);
}
+
+ /**
+ * Get the group ID list pushing IDs in the label stack for the tunnel
+ *
+ * @return List of the group ID
+ */
+ public List<Integer> getGroupIdList() {
+ return this.groupIdList;
+ }
+
}
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplSpringOpenTTP.java b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplSpringOpenTTP.java
index 6b453b8..1fe9c1b 100644
--- a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplSpringOpenTTP.java
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplSpringOpenTTP.java
@@ -1438,7 +1438,7 @@
OFMessage gm = factory.buildGroupDelete()
.setGroup(group)
- // .setGroupType(groupInfo.groupType) /* Due to a bug in CPqD
+ //.setGroupType(groupInfo.groupType) /* Due to a bug in CPqD
// switch */
.setGroupType(OFGroupType.SELECT)
.setXid(getNextTransactionId())
@@ -2068,13 +2068,13 @@
* the labelStack
* @return group identifier
*/
- public int createGroup(List<Integer> labelStack, List<PortNumber> ports) {
+ public List<Integer> createGroup(List<Integer> labelStack, List<PortNumber> ports) {
log.debug("createGroup in sw {} with labelStack {} and ports {}",
getStringId(), labelStack, ports);
if (ports == null) {
log.warn("createGroup in sw {} with wrong input parameters", getStringId());
- return -1;
+ return null;
}
List<PortNumber> activePorts = new ArrayList<PortNumber>();
@@ -2084,10 +2084,11 @@
}
if (activePorts.isEmpty()) {
log.warn("createGroup in sw {} with no active ports", getStringId());
- return -1;
+ return null;
}
int labelStackSize = (labelStack != null) ? labelStack.size() : 0;
+ List<Integer> groupIdList = new ArrayList<Integer>();
/* Filter out disabled ports */
@@ -2121,7 +2122,9 @@
OFGroupType.SELECT, buckets);
setEcmpGroup(ecmpInfo);
userDefinedGroups.put(innermostGroupId, ecmpInfo);
- return innermostGroupId;
+
+ groupIdList.add(innermostGroupId);
+ return groupIdList;
}
/* If the label stack has two or more labels, then a chain of groups
@@ -2147,6 +2150,7 @@
labelStack.get(i).intValue(), false);
lastSetOfGroupIds.put(sp, currGroupId);
userDefinedGroups.put(currGroupId, indirectGroup);
+ groupIdList.add(currGroupId);
}
else if (i == (labelStackSize - 1)) {
/* Innermost label processing */
@@ -2158,6 +2162,7 @@
lastSetOfGroupIds);
userDefinedGroups.put(
innermostGroupId, topLevelGroup);
+ groupIdList.add(innermostGroupId);
break;
}
else {
@@ -2170,12 +2175,13 @@
/* Overwrite with this iteration's group IDs */
lastSetOfGroupIds.put(sp, currGroupId);
userDefinedGroups.put(currGroupId, indirectGroup);
+ groupIdList.add(currGroupId);
}
}
}
log.debug("createGroup in sw{}: group created with innermost group id {}",
getStringId(), innermostGroupId);
- return innermostGroupId;
+ return groupIdList;
}
/**
@@ -2191,10 +2197,11 @@
return false;
}
deleteGroup(group);
+ /*
for (BucketInfo bucket : group.buckets) {
int currGroupIdToBeDeleted = bucket.togroupNo;
while (currGroupIdToBeDeleted != -1) {
- /* Assuming indirect groups with single buckets */
+ // Assuming indirect groups with single buckets
int nextGroupIdToBeDeleted =
userDefinedGroups.get(currGroupIdToBeDeleted).
buckets.get(0).togroupNo;
@@ -2205,6 +2212,7 @@
currGroupIdToBeDeleted = nextGroupIdToBeDeleted;
}
}
+ */
userDefinedGroups.remove(groupId);
log.debug("removeGroup in sw {}: removed group with group id {}",