Avoiding NPE by checking for segment router configuration during sub-driver handshake.
Adding a config file used for 10 switch SR demo.
Change-Id: I3122cdadee2ef73df489550370ef738423a6ab4f
diff --git a/conf/sr-ecmp10-demo.conf b/conf/sr-ecmp10-demo.conf
new file mode 100644
index 0000000..4d972c2
--- /dev/null
+++ b/conf/sr-ecmp10-demo.conf
@@ -0,0 +1,224 @@
+{
+ "comment": " 10 router 3 city topology description and configuration",
+ "restrictSwitches": true,
+ "restrictLinks": true,
+
+ "switchConfig":
+ [
+ { "nodeDpid": "00:01", "name": "SFO-ER1", "type": "Router_SR", "allowed": true,
+ "latitude": 80.80, "longitude": 90.10,
+ "params": { "routerIp": "192.168.0.1/32",
+ "routerMac": "00:00:01:01:01:80",
+ "nodeSid": 101,
+ "isEdgeRouter" : true,
+ "subnets": [
+ { "portNo": 1, "subnetIp": "10.0.1.128/24" }
+ ]
+ }
+ },
+
+ { "nodeDpid": "00:02", "name": "SFO-CR2", "type": "Router_SR", "allowed": true,
+ "latitude": 80.80, "longitude": 90.10,
+ "params": { "routerIp": "192.168.0.2/32",
+ "routerMac": "00:00:02:02:02:80",
+ "nodeSid": 102,
+ "isEdgeRouter" : false,
+ "adjacencySids": [
+ { "adjSid": 12453 , "ports": [ 2 ,3 ] }
+ ]
+ }
+ },
+
+ { "nodeDpid": "00:03", "name": "SFO-CR3", "type": "Router_SR", "allowed": true,
+ "latitude": 80.80, "longitude": 90.10,
+ "params": { "routerIp": "192.168.0.3/32",
+ "routerMac": "00:00:03:03:03:80",
+ "nodeSid": 103,
+ "isEdgeRouter" : false
+ }
+ },
+
+ { "nodeDpid": "00:04", "name": "Dallas-CR4", "type": "Router_SR", "allowed": true,
+ "latitude": 80.80, "longitude": 90.10,
+ "params": { "routerIp": "192.168.0.4/32",
+ "routerMac": "00:00:04:04:04:80",
+ "nodeSid": 104,
+ "isEdgeRouter" : false
+ }
+ },
+
+ { "nodeDpid": "00:05", "name": "Dallas-CR5", "type": "Router_SR", "allowed": true,
+ "latitude": 80.80, "longitude": 90.10,
+ "params": { "routerIp": "192.168.0.5/32",
+ "routerMac": "00:00:05:05:05:80",
+ "nodeSid": 105,
+ "isEdgeRouter" : false
+ }
+ },
+
+ { "nodeDpid": "00:06", "name": "Dallas-ER6", "type": "Router_SR", "allowed": true,
+ "latitude": 80.80, "longitude": 90.10,
+ "params": { "routerIp": "192.168.0.6/32",
+ "routerMac": "00:00:07:07:07:80",
+ "nodeSid": 106,
+ "isEdgeRouter" : true,
+ "subnets": [
+ { "portNo": 1, "subnetIp": "7.7.7.128/24" }
+ ]
+ }
+ },
+
+ { "nodeDpid": "00:07", "name": "NewYork-ER7", "type": "Router_SR", "allowed": true,
+ "latitude": 80.80, "longitude": 90.10,
+ "params": { "routerIp": "192.168.0.7/32",
+ "routerMac": "00:00:00:00:07:80",
+ "nodeSid": 107,
+ "isEdgeRouter" : true,
+ "adjacencySids": [
+ { "adjSid": 12345 , "ports": [ 2 ,3 ] }
+ ],
+ "subnets": [
+ { "portNo": 1, "subnetIp": "10.1.1.128/24" }
+ ]
+ }
+ },
+
+ { "nodeDpid": "00:08", "name": "NewYork-CR8", "type": "Router_SR", "allowed": true,
+ "latitude": 80.80, "longitude": 90.10,
+ "params": { "routerIp": "192.168.0.8/32",
+ "routerMac": "00:00:00:00:08:80",
+ "nodeSid": 108,
+ "isEdgeRouter" : false,
+ "adjacencySids": [
+ { "adjSid": 88888, "ports": [ 3, 6, 4 ] }
+ ]
+
+ }
+ },
+
+ { "nodeDpid": "00:09", "name": "NewYork-CR9", "type": "Router_SR", "allowed": true,
+ "latitude": 80.80, "longitude": 90.10,
+ "params": { "routerIp": "192.168.0.9/32",
+ "routerMac": "00:00:00:00:09:80",
+ "nodeSid": 109,
+ "isEdgeRouter" : false
+ }
+ },
+
+ { "nodeDpid": "00:0a", "name": "NewYork-ER10", "type": "Router_SR", "allowed": true,
+ "latitude": 80.80, "longitude": 90.10,
+ "params": { "routerIp": "192.168.0.10/32",
+ "routerMac": "00:00:00:00:0a:80",
+ "nodeSid": 110,
+ "isEdgeRouter" : true,
+ "subnets": [
+ { "portNo": 1, "subnetIp": "10.1.2.128/24" }
+ ]
+ }
+ }
+
+ ],
+
+ "linkConfig":[
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "01", "nodeDpid2": "02",
+ "params": { "port1": 2, "port2": 1 }
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "01", "nodeDpid2": "03",
+ "params": { "port1": 3, "port2": 1 }
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "02", "nodeDpid2": "03",
+ "params": { "port1": 2, "port2": 2 }
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "02", "nodeDpid2": "05",
+ "params": { "port1": 3, "port2": 1 }
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "03", "nodeDpid2": "04",
+ "params": { "port1": 3, "port2": 1 }
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "04", "nodeDpid2": "05",
+ "params": { "port1": 2, "port2": 2 }
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "04", "nodeDpid2": "06",
+ "params": { "port1": 3, "port2": 2 }
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "05", "nodeDpid2": "06",
+ "params": { "port1": 3, "port2": 3 }
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "07", "nodeDpid2": "08",
+ "params": { "port1": 2, "port2": 1 }
+ },
+
+
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "09", "nodeDpid2": "0a",
+ "params": { "port1": 2, "port2": 2}
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "02", "nodeDpid2": "09",
+ "params": { "port1": 4, "port2": 3 }
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "02", "nodeDpid2": "08",
+ "params": { "port1": 5, "port2": 3 }
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "05", "nodeDpid2": "08",
+ "params": { "port1": 4, "port2": 4 }
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "08", "nodeDpid2": "0a",
+ "params": { "port1": 5, "port2": 3}
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "09", "nodeDpid2": "07",
+ "params": { "port1": 4, "port2": 3}
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "09", "nodeDpid2": "08",
+ "params": { "port1": 1, "port2": 2}
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "01", "nodeDpid2": "03",
+ "params": { "port1": 4, "port2": 4}
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "02", "nodeDpid2": "08",
+ "params": { "port1": 6, "port2": 6}
+ },
+
+ { "type": "pktLink", "allowed": true,
+ "nodeDpid1": "09", "nodeDpid2": "05",
+ "params": { "port1": 5, "port2": 5}
+ }
+
+
+ ]
+
+}
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 382513e..fa1e517 100644
--- a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplSpringOpenTTP.java
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplSpringOpenTTP.java
@@ -185,7 +185,6 @@
// OFSwitchImplBase
// *****************************
-
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@@ -238,139 +237,6 @@
return driverState.toString();
}
- public void removePortFromGroups(PortNumber port) {
- log.debug("removePortFromGroups: Remove port {} from Switch {}",
- port, getStringId());
- HashSet<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;
- }
- log.debug("removePortFromGroups: Neighborsets that the port {} is part"
- + "of on Switch {} are {}",
- port, getStringId(), portNSSet);
-
- for (NeighborSet ns : portNSSet) {
- /* Delete the first matched bucket */
- EcmpInfo portEcmpInfo = ecmpGroups.get(ns);
- if (portEcmpInfo == null) {
- /* No groups present for this neighbor set */
- continue;
- }
- Iterator<BucketInfo> it = portEcmpInfo.buckets.iterator();
- log.debug("removePortFromGroups: Group {} on Switch {} has {} buckets",
- portEcmpInfo.groupId, getStringId(),
- portEcmpInfo.buckets.size());
- while (it.hasNext()) {
- BucketInfo bucket = it.next();
- if (bucket.outport.equals(port)) {
- it.remove();
- }
- }
- log.debug("removePortFromGroups: Modifying Group on Switch {} "
- + "and Neighborset {} with {}",
- getStringId(), ns, portEcmpInfo);
- modifyEcmpGroup(portEcmpInfo);
- }
- /* Don't delete the entry from portNeighborSetMap because
- * when the port is up again this info is needed
- */
- return;
- }
-
- public void addPortToGroups(PortNumber port) {
- log.debug("addPortToGroups: Add port {} to Switch {}",
- port, getStringId());
- if (!portEnabled((int) (port.value())))
- {
- log.warn("addPortToGroups: Switch {} port {} is not ACTIVE",
- getStringId(), port);
- return;
- }
- HashSet<NeighborSet> portNSSet = portNeighborSetMap.get(port);
- if (portNSSet == null) {
- /* Unknown Port */
- log.warn("addPortToGroups: Switch {} port {} is unknown or "
- + "there were no groups existing with the neighbor dpid"
- + "that it is reachable through this port",
- getStringId(), port);
- return;
- }
- log.debug("addPortToGroups: Neighborsets that the port {} is part"
- + "of on Switch {} are {}",
- port, getStringId(), portNSSet);
-
- Dpid neighborDpid = portToNeighbors.get(port);
- for (NeighborSet ns : portNSSet) {
- EcmpInfo portEcmpInfo = ecmpGroups.get(ns);
- /* Find if this port is already part of any bucket
- * in this group
- * NOTE: This is needed because in some cases
- * (such as for configured network nodes), both driver and
- * application detect the network elements and creates the
- * buckets in the same group. This check is to avoid
- * duplicate bucket creation in such scenarios
- */
- List<BucketInfo> buckets = null;
-
- if (portEcmpInfo != null) {
- buckets = portEcmpInfo.buckets;
- if (buckets == null) {
- buckets = new ArrayList<BucketInfo>();
- portEcmpInfo.buckets = buckets;
- } else {
- Iterator<BucketInfo> it = buckets.iterator();
- boolean matchingBucketExist = false;
- while (it.hasNext()) {
- BucketInfo bucket = it.next();
- if (bucket.outport.equals(port)) {
- matchingBucketExist = true;
- break;
- }
- }
- if (matchingBucketExist) {
- log.warn("addPortToGroups: On Switch {} duplicate "
- + "portAdd is called for port {} with buckets {}",
- getStringId(), port, buckets);
- continue;
- }
- }
- }
- else
- {
- /* The group is getting created for the first time
- * for this neighborset
- */
- buckets = new ArrayList<BucketInfo>();
- }
- BucketInfo b = new BucketInfo(neighborDpid,
- MacAddress.of(srConfig.getRouterMac()),
- getNeighborRouterMacAddress(neighborDpid, ns.getOutPktType()),
- port,
- ns.getEdgeLabel(), true, -1);
- buckets.add(b);
- if (portEcmpInfo != null) {
- log.debug("addPortToGroups: Modifying Group on Switch {} "
- + "and Neighborset {} with {}",
- getStringId(), ns, portEcmpInfo);
- modifyEcmpGroup(portEcmpInfo);
- }
- else {
- int groupId = groupid.incrementAndGet();
- portEcmpInfo = new EcmpInfo(groupId, OFGroupType.SELECT, buckets);
- log.debug("addPortToGroups: Creating Group on Switch {} "
- + "and Neighborset {} with {}",
- getStringId(), ns, portEcmpInfo);
- setEcmpGroup(portEcmpInfo);
- }
-
- }
- return;
- }
-
@Override
public OrderedCollection<PortChangeEvent> processOFPortStatus(OFPortStatus ps) {
OrderedCollection<PortChangeEvent> events = super.processOFPortStatus(ps);
@@ -420,7 +286,10 @@
break;
case SET_TABLE_MISS_ENTRIES:
driverState = DriverState.SET_TABLE_VLAN_TMAC;
- getNetworkConfig();
+ boolean isConfigured = getNetworkConfig();
+ if (!isConfigured) {
+ return; // this will result in a handshake timeout
+ }
populateTableVlan();
populateTableTMac();
sendHandshakeBarrier();
@@ -651,16 +520,20 @@
write(tableMissEntry, null);
}
- private void getNetworkConfig() {
+ private boolean getNetworkConfig() {
INetworkConfigService ncs = floodlightProvider.getNetworkConfigService();
SwitchConfigStatus scs = ncs.checkSwitchConfig(new Dpid(getId()));
- if (scs.getConfigState() == NetworkConfigState.ACCEPT_ADD) {
- srConfig = (SegmentRouterConfig) scs.getSwitchConfig();
- isEdgeRouter = srConfig.isEdgeRouter();
- } else {
- log.error("Switch not configured as Segment-Router");
+ if (scs.getConfigState() != NetworkConfigState.ACCEPT_ADD) {
+ log.error("Switch {} is not configured as Segment-Router.. aborting",
+ getStringId());
+ return false;
}
-
+ srConfig = (SegmentRouterConfig) scs.getSwitchConfig();
+ if (srConfig == null) {
+ log.error("Switch {} configuration is null.. aborting", getStringId());
+ return false;
+ }
+ isEdgeRouter = srConfig.isEdgeRouter();
List<LinkConfig> linkConfigList = ncs.getConfiguredAllowedLinks();
setNeighbors(linkConfigList);
@@ -668,6 +541,7 @@
List<SwitchConfig> switchList = ncs.getConfiguredAllowedSwitches();
getAllNodeSegmentIds(switchList);
}
+ return true;
}
private void populateTableVlan() throws IOException {
@@ -2049,6 +1923,139 @@
return publishAttributes;
}
+ public void removePortFromGroups(PortNumber port) {
+ log.debug("removePortFromGroups: Remove port {} from Switch {}",
+ port, getStringId());
+ HashSet<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;
+ }
+ log.debug("removePortFromGroups: Neighborsets that the port {} is part"
+ + "of on Switch {} are {}",
+ port, getStringId(), portNSSet);
+
+ for (NeighborSet ns : portNSSet) {
+ /* Delete the first matched bucket */
+ EcmpInfo portEcmpInfo = ecmpGroups.get(ns);
+ if (portEcmpInfo == null) {
+ /* No groups present for this neighbor set */
+ continue;
+ }
+ Iterator<BucketInfo> it = portEcmpInfo.buckets.iterator();
+ log.debug("removePortFromGroups: Group {} on Switch {} has {} buckets",
+ portEcmpInfo.groupId, getStringId(),
+ portEcmpInfo.buckets.size());
+ while (it.hasNext()) {
+ BucketInfo bucket = it.next();
+ if (bucket.outport.equals(port)) {
+ it.remove();
+ }
+ }
+ log.debug("removePortFromGroups: Modifying Group on Switch {} "
+ + "and Neighborset {} with {}",
+ getStringId(), ns, portEcmpInfo);
+ modifyEcmpGroup(portEcmpInfo);
+ }
+ /* Don't delete the entry from portNeighborSetMap because
+ * when the port is up again this info is needed
+ */
+ return;
+ }
+
+ public void addPortToGroups(PortNumber port) {
+ log.debug("addPortToGroups: Add port {} to Switch {}",
+ port, getStringId());
+ if (!portEnabled((int) (port.value())))
+ {
+ log.warn("addPortToGroups: Switch {} port {} is not ACTIVE",
+ getStringId(), port);
+ return;
+ }
+ HashSet<NeighborSet> portNSSet = portNeighborSetMap.get(port);
+ if (portNSSet == null) {
+ /* Unknown Port */
+ log.warn("addPortToGroups: Switch {} port {} is unknown or "
+ + "there were no groups existing with the neighbor dpid"
+ + "that it is reachable through this port",
+ getStringId(), port);
+ return;
+ }
+ log.debug("addPortToGroups: Neighborsets that the port {} is part"
+ + "of on Switch {} are {}",
+ port, getStringId(), portNSSet);
+
+ Dpid neighborDpid = portToNeighbors.get(port);
+ for (NeighborSet ns : portNSSet) {
+ EcmpInfo portEcmpInfo = ecmpGroups.get(ns);
+ /* Find if this port is already part of any bucket
+ * in this group
+ * NOTE: This is needed because in some cases
+ * (such as for configured network nodes), both driver and
+ * application detect the network elements and creates the
+ * buckets in the same group. This check is to avoid
+ * duplicate bucket creation in such scenarios
+ */
+ List<BucketInfo> buckets = null;
+
+ if (portEcmpInfo != null) {
+ buckets = portEcmpInfo.buckets;
+ if (buckets == null) {
+ buckets = new ArrayList<BucketInfo>();
+ portEcmpInfo.buckets = buckets;
+ } else {
+ Iterator<BucketInfo> it = buckets.iterator();
+ boolean matchingBucketExist = false;
+ while (it.hasNext()) {
+ BucketInfo bucket = it.next();
+ if (bucket.outport.equals(port)) {
+ matchingBucketExist = true;
+ break;
+ }
+ }
+ if (matchingBucketExist) {
+ log.warn("addPortToGroups: On Switch {} duplicate "
+ + "portAdd is called for port {} with buckets {}",
+ getStringId(), port, buckets);
+ continue;
+ }
+ }
+ }
+ else
+ {
+ /* The group is getting created for the first time
+ * for this neighborset
+ */
+ buckets = new ArrayList<BucketInfo>();
+ }
+ BucketInfo b = new BucketInfo(neighborDpid,
+ MacAddress.of(srConfig.getRouterMac()),
+ getNeighborRouterMacAddress(neighborDpid, ns.getOutPktType()),
+ port,
+ ns.getEdgeLabel(), true, -1);
+ buckets.add(b);
+ if (portEcmpInfo != null) {
+ log.debug("addPortToGroups: Modifying Group on Switch {} "
+ + "and Neighborset {} with {}",
+ getStringId(), ns, portEcmpInfo);
+ modifyEcmpGroup(portEcmpInfo);
+ }
+ else {
+ int groupId = groupid.incrementAndGet();
+ portEcmpInfo = new EcmpInfo(groupId, OFGroupType.SELECT, buckets);
+ log.debug("addPortToGroups: Creating Group on Switch {} "
+ + "and Neighborset {} with {}",
+ getStringId(), ns, portEcmpInfo);
+ setEcmpGroup(portEcmpInfo);
+ }
+
+ }
+ return;
+ }
+
// *****************************
// Unused
// *****************************