Avoiding neighborsets with same edgelabel as nodes
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 74dc0de..ca2d6af 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
@@ -348,7 +348,7 @@
IOF13Switch dstSw = (IOF13Switch) floodlightProvider.getMasterSwitch(
getSwId(dstPort.getDpid().toString()));
// TODO: please enable it when driver feature is implemented
- //dstSw.removePortFromGroups(dstPort.getNumber());
+ dstSw.removePortFromGroups(dstPort.getNumber());
log.debug("MasterSwitch {} is gone: remove port {}", sw.getDpid(), dstPort);
}
@@ -370,7 +370,7 @@
IOF13Switch dstSw = (IOF13Switch) floodlightProvider.getMasterSwitch(
getSwId(dstPort.getDpid().toString()));
if (dstSw != null) {
- //dstSw.removePortFromGroups(dstPort.getNumber());
+ dstSw.removePortFromGroups(dstPort.getNumber());
log.debug("Switch {} is gone: remove port {}", sw.getDpid(), dstPort);
}
}
@@ -459,12 +459,11 @@
getSwId(srcPort.getDpid().toString()));
IOF13Switch dstSw = (IOF13Switch) floodlightProvider.getMasterSwitch(
getSwId(srcPort.getDpid().toString()));
- /*
+
if (srcSw != null)
srcSw.removePortFromGroups(srcPort.getPortNumber());
if (dstSw != null)
dstSw.removePortFromGroups(dstPort.getPortNumber());
- */
Switch srcSwitch = mutableTopology.getSwitch(srcPort.getDpid());
if (srcSwitch.getLinkToNeighbor(dstPort.getDpid()) == null) {
@@ -486,7 +485,6 @@
* @param portEntries
*/
private void processPortRemoval(Collection<PortData> portEntries) {
- /*
for (PortData port : portEntries) {
Dpid dpid = port.getDpid();
@@ -496,7 +494,6 @@
sw.removePortFromGroups(port.getPortNumber());
log.debug("Remove port {} from switch {}", port, dpid);
}
- */
}
/**
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
index 640d7eb..42e4de1 100644
--- a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
@@ -130,8 +130,10 @@
private final boolean usePipeline13;
private SegmentRouterConfig srConfig;
private ConcurrentMap<Dpid, Set<PortNumber>> neighbors;
+ private ConcurrentMap<PortNumber, Dpid> portToNeighbors;
private List<Integer> edgeLabels;
private boolean isEdgeRouter;
+ private int sid;
private ConcurrentMap<NeighborSet, EcmpInfo> ecmpGroups;
private ConcurrentMap<PortNumber, ArrayList<NeighborSet>> portNeighborSetMap;
@@ -144,6 +146,7 @@
driverHandshakeComplete = new AtomicBoolean(false);
setSwitchDescription(desc);
neighbors = new ConcurrentHashMap<Dpid, Set<PortNumber>>();
+ portToNeighbors = new ConcurrentHashMap<PortNumber, Dpid>();
ecmpGroups = new ConcurrentHashMap<NeighborSet, EcmpInfo>();
portNeighborSetMap =
new ConcurrentHashMap<PortNumber, ArrayList<NeighborSet>>();
@@ -212,8 +215,12 @@
public void removePortFromGroups(PortNumber port) {
ArrayList<NeighborSet> portNSSet = portNeighborSetMap.get(port);
if (portNSSet == null)
+ {
/* No Groups are created with this port yet */
+ log.warn("removePortFromGroups: No groups exist with Switch {} port {}",
+ getStringId(), port);
return;
+ }
for (NeighborSet ns : portNSSet) {
/* Delete the first matched bucket */
EcmpInfo portEcmpInfo = ecmpGroups.get(ns);
@@ -222,37 +229,43 @@
BucketInfo bucket = it.next();
if (bucket.outport.equals(port)) {
it.remove();
- /* Assuming port appears under only one bucket for
- * a neighbor set and hence invoking Group modify command
- */
- modifyEcmpGroup(portEcmpInfo);
- break;
}
}
+ modifyEcmpGroup(portEcmpInfo);
}
- /* Delete entry from portNeighborSetMap */
- portNeighborSetMap.remove(port);
+ /* Don't delete the entry from portNeighborSetMap because
+ * when the port is up again this info is needed
+ */
return;
}
public void addPortToGroups(PortNumber port) {
ArrayList<NeighborSet> portNSSet = portNeighborSetMap.get(port);
- if (portNSSet != null) {
- /* Port is already part of ECMP groups */
+ if (portNSSet == null) {
+ /* Unknown Port */
+ log.warn("addPortToGroups: Switch {} port {} is unknown",
+ getStringId(), port);
return;
}
- /* TODO:
- * 1) Find the neighbors reached from this port
- * 2) Compute the Neighbor sets
- * 3) For the Neighbor set entries that are already there
- * in the database,
- * a) Update the ecmpGroups hashmap
- * b) perform Group Modify on updated groups
- * 4) For the new Neighbor set entries, add an entry in the database
- * a) Add entry to the ecmpGroups hashmap
- * b) perform Group Add on those groups
- * 5) Update the portNeighborSetMap hashmap
- * */
+ Dpid neighborDpid = portToNeighbors.get(port);
+ for (NeighborSet ns : portNSSet) {
+ /* Delete the first matched bucket */
+ EcmpInfo portEcmpInfo = ecmpGroups.get(ns);
+ BucketInfo b = new BucketInfo(neighborDpid,
+ MacAddress.of(srConfig.getRouterMac()),
+ getNeighborRouterMacAddress(neighborDpid),
+ port,
+ ns.getEdgeLabel());
+ List<BucketInfo> buckets = portEcmpInfo.buckets;
+ if (buckets == null) {
+ buckets = new ArrayList<BucketInfo>();
+ buckets.add(b);
+ portEcmpInfo.buckets = buckets;
+ } else {
+ buckets.add(b);
+ }
+ modifyEcmpGroup(portEcmpInfo);
+ }
return;
}
@@ -519,6 +532,7 @@
if (scs.getConfigState() == NetworkConfigState.ACCEPT_ADD) {
srConfig = (SegmentRouterConfig) scs.getSwitchConfig();
isEdgeRouter = srConfig.isEdgeRouter();
+ sid = srConfig.getNodeSid();
} else {
log.error("Switch not configured as Segment-Router");
}
@@ -680,6 +694,7 @@
}
private void addNeighborAtPort(Dpid neighborDpid, PortNumber portToNeighbor) {
+ /* Update NeighborToPort database */
if (neighbors.get(neighborDpid) != null) {
neighbors.get(neighborDpid).add(portToNeighbor);
} else {
@@ -687,6 +702,10 @@
ports.add(portToNeighbor);
neighbors.put(neighborDpid, ports);
}
+
+ /* Update portToNeighbors database */
+ if (portToNeighbors.get(portToNeighbor) == null)
+ portToNeighbors.put(portToNeighbor, neighborDpid);
}
private void getAllEdgeLabels(List<SwitchConfig> switchList) {
@@ -702,6 +721,18 @@
}
}
+ private boolean isNodeLabelAndEdgeLabelSame(Dpid dpid, int edgeLabel) {
+ INetworkConfigService ncs = floodlightProvider.getNetworkConfigService();
+ SwitchConfigStatus scs = ncs.checkSwitchConfig(dpid);
+ if (scs.getConfigState() == NetworkConfigState.ACCEPT_ADD) {
+ return (((SegmentRouterConfig) scs.getSwitchConfig()).
+ getNodeSid() == edgeLabel);
+ } else {
+ // TODO: return false if router not allowed
+ return false;
+ }
+ }
+
private Set<Set<Dpid>> getAllNeighborSets(Set<Dpid> neighbors) {
List<Dpid> list = new ArrayList<Dpid>(neighbors);
Set<Set<Dpid>> sets = new HashSet<Set<Dpid>>();
@@ -720,19 +751,21 @@
dpidSubSet.add(list.get(j));
}
}
- boolean allEdgeRouters = true;
- if (dpidSubSet.size() > 1) {
+ /* NOTE: Avoid any pairings of edge routers only
+ * at a backbone router */
+ boolean avoidEdgeRouterPairing = true;
+ if ((!isEdgeRouter) && (dpidSubSet.size() > 1)) {
for (Dpid dpid : dpidSubSet) {
if (!isEdgeRouter(dpid)) {
- allEdgeRouters = false;
+ avoidEdgeRouterPairing = false;
break;
}
}
}
else
- allEdgeRouters = false;
+ avoidEdgeRouterPairing = false;
- if (!allEdgeRouters)
+ if (!avoidEdgeRouterPairing)
sets.add(dpidSubSet);
}
return sets;
@@ -770,11 +803,23 @@
Set<Set<Dpid>> powerSet = getAllNeighborSets(dpids);
Set<NeighborSet> nsSet = new HashSet<NeighborSet>();
for (Set<Dpid> combo : powerSet) {
+ if (combo.isEmpty())
+ continue;
if (isEdgeRouter && !edgeLabels.isEmpty()) {
for (Integer edgeLabel : edgeLabels) {
+ /* If it is local node's edge label, continue */
+ if (edgeLabel == sid)
+ continue;
NeighborSet ns = new NeighborSet();
ns.addDpids(combo);
- ns.setEdgeLabel(edgeLabel);
+ /* Check if the edge label being set is of the
+ * same node in the Neighbor set
+ */
+ if ((combo.size() != 1) ||
+ (!isNodeLabelAndEdgeLabelSame(
+ combo.iterator().next(), edgeLabel))){
+ ns.setEdgeLabel(edgeLabel);
+ }
nsSet.add(ns);
}
} else {
@@ -940,8 +985,10 @@
if (b.mplsLabel != -1) {
OFAction pushLabel = factory.actions().buildPushMpls()
.setEthertype(EthType.MPLS_UNICAST).build();
- OFAction setLabel = factory.actions().buildSetMplsLabel()
- .setMplsLabel(b.mplsLabel).build();
+ OFOxmMplsLabel lid = factory.oxms()
+ .mplsLabel(U32.of(b.mplsLabel));
+ OFAction setLabel = factory.actions().buildSetField()
+ .setField(lid).build();
OFAction copyTtl = factory.actions().copyTtlOut();
OFAction decrTtl = factory.actions().decMplsTtl();
actions.add(pushLabel);