- Added more null check in IcmpHandler
 - "isEdgeRouter" field is added in params of network configuration file

Change-Id: I749499dd7c63a8f9e732a144d705bcf3e09af02d
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java b/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
index 9366a2e..bca4bd5 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/IcmpHandler.java
@@ -105,8 +105,8 @@
 
             if (ipv4.getProtocol() == IPv4.PROTOCOL_ICMP) {
 
-                log.debug("ICMPHandler: Received a ICMP packet {} from sw {} ",
-                        payload.toString(), sw.getDpid());
+                log.debug("Received an ICMP packet from sw {} ",
+                        sw.getDpid());
                 IPv4Address destinationAddress =
                         IPv4Address.of(ipv4.getDestinationAddress());
 
@@ -120,7 +120,7 @@
                     if (((ICMP) ipv4.getPayload()).getIcmpType() == ICMP_TYPE_ECHO &&
                             (destinationAddress.getInt() == switchIpAddress.getInt() ||
                             gatewayIps.contains(destinationAddress.toString()))) {
-                        log.debug("ICMPHandler: ICMP packet for sw {} and "
+                        log.debug("ICMP packet for sw {} and "
                                 + "sending ICMP response ", sw.getDpid());
                         sendICMPResponse(sw, inPort, payload);
                         srManager.getIpPacketFromQueue(destinationAddress.getBytes());
@@ -166,8 +166,8 @@
                     }
                 }
                 /* ICMP for an unknown host */
-                log.debug("ICMPHandler: ICMP request for unknown host {}"
-                        + " and sending ARP request", destinationAddress);
+                log.debug("ICMPHandler: ICMP request for unknown host {}",
+                        destinationAddress);
                 srManager.sendArpRequest(sw, destinationAddress.getInt(), inPort);
             }
 
@@ -283,6 +283,9 @@
             // and the destination is not the neighbor switch, then add MPLS
             // label
             String targetMac = getRouterMACFromConfig(targetAddress);
+            if (targetMac == null) {
+                return; // targetMac should be always available
+            }
             if (!sameSubnet && !targetMac.equals(destMacAddress)) {
                 int mplsLabel = getMplsLabelFromConfig(targetAddress);
                 if (mplsLabel > 0) {
diff --git a/src/main/java/net/onrc/onos/core/configmanager/SegmentRouterConfig.java b/src/main/java/net/onrc/onos/core/configmanager/SegmentRouterConfig.java
index 58121e2..89df3c6 100644
--- a/src/main/java/net/onrc/onos/core/configmanager/SegmentRouterConfig.java
+++ b/src/main/java/net/onrc/onos/core/configmanager/SegmentRouterConfig.java
@@ -23,6 +23,7 @@
     private String routerIp;
     private String routerMac;
     private int nodeSid;
+    private boolean isEdgeRouter;
     private List<AdjacencySid> adjacencySids;
     private List<Subnet> subnets;
 
@@ -31,6 +32,7 @@
     public static final String NODE_SID = "nodeSid";
     public static final String ADJACENCY_SIDS = "adjacencySids";
     public static final String SUBNETS = "subnets";
+    public static final String ISEDGE = "isEdgeRouter";
 
     public SegmentRouterConfig(SwitchConfig swc) {
         this.setName(swc.getName());
@@ -75,6 +77,14 @@
         this.nodeSid = nodeSid;
     }
 
+    public boolean isEdgeRouter() {
+        return isEdgeRouter;
+    }
+
+    public void setIsEdgeRouter(boolean isEdge) {
+        this.isEdgeRouter = isEdge;
+    }
+
     public static class AdjacencySid {
         private int portNo;
         private int adjSid;
@@ -162,7 +172,10 @@
                 setRouterMac(j.asText());
             } else if (key.equals("nodeSid")) {
                 setNodeSid(j.asInt());
-            } else if (key.equals("adjacencySids") || key.equals("subnets")) {
+            } else if (key.equals("isEdgeRouter")) {
+                setIsEdgeRouter(j.asBoolean());
+            }
+            else if (key.equals("adjacencySids") || key.equals("subnets")) {
                 getInnerParams(j, key);
             } else {
                 throw new UnknownSegmentRouterConfig(key, dpid);
@@ -203,6 +216,12 @@
         if (routerIp == null) {
             throw new IpNotSpecified(dpid);
         }
+        if (isEdgeRouter && subnets.isEmpty()) {
+            throw new SubnetNotSpecifiedInEdgeRouter(dpid);
+        }
+        if (!isEdgeRouter && !subnets.isEmpty()) {
+            throw new SubnetSpecifiedInBackboneRouter(dpid);
+        }
 
         // TODO more validations
     }
@@ -216,6 +235,7 @@
         publishAttributes.put(ROUTER_IP, routerIp);
         publishAttributes.put(ROUTER_MAC, routerMac);
         publishAttributes.put(NODE_SID, String.valueOf(nodeSid));
+        publishAttributes.put(ISEDGE, String.valueOf(isEdgeRouter));
         ObjectMapper mapper = new ObjectMapper();
         try {
             publishAttributes.put(ADJACENCY_SIDS,
@@ -253,5 +273,26 @@
         }
     }
 
+    public static class SubnetNotSpecifiedInEdgeRouter extends RuntimeException {
+        private static final long serialVersionUID = -5855458472668581268L;
+
+        public SubnetNotSpecifiedInEdgeRouter(long dpid) {
+            super();
+            log.error("Subnet was not specified for edge router in dpid: {}",
+                    HexString.toHexString(dpid));
+        }
+    }
+
+    public static class SubnetSpecifiedInBackboneRouter extends RuntimeException {
+        private static final long serialVersionUID = -5855458472668581268L;
+
+        public SubnetSpecifiedInBackboneRouter(long dpid) {
+            super();
+            log.error("Subnet was specified in backbone router in dpid: {}",
+                    HexString.toHexString(dpid));
+        }
+    }
+
+
 
 }