[CORD-520] IPv6 routing

Changes:
- Adds support for IPv6 host routing in the fabric;

Change-Id: I07369500de48f0945f09a5a1e8ab4c98be37978e
diff --git a/src/main/java/org/onosproject/segmentrouting/HostHandler.java b/src/main/java/org/onosproject/segmentrouting/HostHandler.java
index c3022ff..cf49c52 100644
--- a/src/main/java/org/onosproject/segmentrouting/HostHandler.java
+++ b/src/main/java/org/onosproject/segmentrouting/HostHandler.java
@@ -103,7 +103,7 @@
 
             ips.forEach(ip -> {
                 // Populate IP table entry
-                if (ip.isIp4() && srManager.deviceConfiguration.inSameSubnet(location, ip)) {
+                if (srManager.deviceConfiguration.inSameSubnet(location, ip)) {
                     srManager.routingRulePopulator.populateRoute(
                             deviceId, ip.toIpPrefix(), mac, port);
                 }
@@ -140,7 +140,7 @@
 
             // Revoke IP table entry
             ips.forEach(ip -> {
-                if (ip.isIp4() && srManager.deviceConfiguration.inSameSubnet(location, ip)) {
+                if (srManager.deviceConfiguration.inSameSubnet(location, ip)) {
                     srManager.routingRulePopulator.revokeRoute(
                             deviceId, ip.toIpPrefix(), mac, port);
                 }
@@ -178,7 +178,7 @@
 
             // Revoke previous IP table entry
             prevIps.forEach(ip -> {
-                if (ip.isIp4() && srManager.deviceConfiguration.inSameSubnet(prevLocation, ip)) {
+                if (srManager.deviceConfiguration.inSameSubnet(prevLocation, ip)) {
                     srManager.routingRulePopulator.revokeRoute(
                             prevDeviceId, ip.toIpPrefix(), mac, prevPort);
                 }
@@ -201,7 +201,7 @@
 
             // Populate new IP table entry
             newIps.forEach(ip -> {
-                if (ip.isIp4() && srManager.deviceConfiguration.inSameSubnet(newLocation, ip)) {
+                if (srManager.deviceConfiguration.inSameSubnet(newLocation, ip)) {
                     srManager.routingRulePopulator.populateRoute(
                             newDeviceId, ip.toIpPrefix(), mac, newPort);
                 }
@@ -225,7 +225,7 @@
         if (accepted(event.prevSubject())) {
             // Revoke previous IP table entry
             prevIps.forEach(ip -> {
-                if (ip.isIp4() && srManager.deviceConfiguration.inSameSubnet(prevLocation, ip)) {
+                if (srManager.deviceConfiguration.inSameSubnet(prevLocation, ip)) {
                     srManager.routingRulePopulator.revokeRoute(
                             prevDeviceId, ip.toIpPrefix(), mac, prevPort);
                 }
@@ -235,7 +235,7 @@
         if (accepted(event.subject())) {
             // Populate new IP table entry
             newIps.forEach(ip -> {
-                if (ip.isIp4() && srManager.deviceConfiguration.inSameSubnet(newLocation, ip)) {
+                if (srManager.deviceConfiguration.inSameSubnet(newLocation, ip)) {
                     srManager.routingRulePopulator.populateRoute(
                             newDeviceId, ip.toIpPrefix(), mac, newPort);
                 }
diff --git a/src/main/java/org/onosproject/segmentrouting/RouteHandler.java b/src/main/java/org/onosproject/segmentrouting/RouteHandler.java
index 694e1b0..1741608 100644
--- a/src/main/java/org/onosproject/segmentrouting/RouteHandler.java
+++ b/src/main/java/org/onosproject/segmentrouting/RouteHandler.java
@@ -59,8 +59,8 @@
         MacAddress nextHopMac = route.nextHopMac();
         ConnectPoint location = route.location();
 
-        srManager.deviceConfiguration.addSubnet(location, prefix.getIp4Prefix());
-        srManager.defaultRoutingHandler.populateSubnet(location, ImmutableSet.of(prefix.getIp4Prefix()));
+        srManager.deviceConfiguration.addSubnet(location, prefix);
+        srManager.defaultRoutingHandler.populateSubnet(location, ImmutableSet.of(prefix));
         srManager.routingRulePopulator.populateRoute(location.deviceId(), prefix,
                 nextHopMac, location.port());
     }
diff --git a/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
index 1ea185e..48c988c 100644
--- a/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
+++ b/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -188,9 +188,7 @@
         MacAddress deviceMac;
         deviceMac = config.getDeviceMac(deviceId);
 
-        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
-        sbuilder.matchEthType(Ethernet.TYPE_IPV4);
-        sbuilder.matchIPDst(prefix);
+        TrafficSelector.Builder sbuilder = buildIpSelectorFromIpPrefix(prefix);
         TrafficSelector selector = sbuilder.build();
 
         TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
@@ -202,7 +200,7 @@
 
         // All forwarding is via Groups. Drivers can re-purpose to flow-actions if needed.
         // for switch pipelines that need it, provide outgoing vlan as metadata
-        VlanId outvlan = null;
+        VlanId outvlan;
         Ip4Prefix subnet = srManager.deviceConfiguration.getPortIPv4Subnet(deviceId, outPort);
         if (subnet == null) {
             outvlan = VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET);
@@ -349,9 +347,7 @@
      * @return true if all rules are removed successfully, false otherwise
      */
     public boolean revokeIpRuleForRouter(IpPrefix ipPrefix) {
-        TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
-        sbuilder.matchIPDst(ipPrefix);
-        sbuilder.matchEthType(Ethernet.TYPE_IPV4);
+        TrafficSelector.Builder sbuilder = buildIpSelectorFromIpPrefix(ipPrefix);
         TrafficSelector selector = sbuilder.build();
         TrafficTreatment dummyTreatment = DefaultTrafficTreatment.builder().build();
 
@@ -790,10 +786,14 @@
      */
     public void populateSubnetBroadcastRule(DeviceId deviceId) {
         config.getSubnets(deviceId).forEach(subnet -> {
-            if (subnet.prefixLength() == 0 ||
-                    subnet.prefixLength() == IpPrefix.MAX_INET_MASK_LENGTH ||
-                    subnet.prefixLength() == IpPrefix.MAX_INET6_MASK_LENGTH) {
-                return;
+            if (subnet.isIp4()) {
+                if (subnet.prefixLength() == 0 || subnet.prefixLength() == IpPrefix.MAX_INET_MASK_LENGTH) {
+                    return;
+                }
+            } else {
+                if (subnet.prefixLength() == 0 || subnet.prefixLength() == IpPrefix.MAX_INET6_MASK_LENGTH) {
+                    return;
+                }
             }
             int nextId = srManager.getSubnetNextObjectiveId(deviceId, subnet);
             VlanId vlanId = srManager.getSubnetAssignedVlanId(deviceId, subnet);
diff --git a/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index 6694aea..1316285 100644
--- a/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -656,6 +656,7 @@
                 log.warn("{} - we are still receiving ARP packets from {}",
                          context.inPacket().receivedFrom());
                 log.debug("{}", ethernet);
+                return;
             } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
                 IPv4 ipv4Packet = (IPv4) ethernet.getPayload();
                 //ipHandler.addToPacketBuffer(ipv4Packet);
@@ -664,7 +665,7 @@
                 } else {
                     // NOTE: We don't support IP learning at this moment so this
                     //       is not necessary. Also it causes duplication of DHCP packets.
-                    // ipHandler.processPacketIn(pkt);
+                    // ipHandler.processPacketIn(ipv4Packet, pkt.receivedFrom());
                 }
             } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV6) {
                 IPv6 ipv6Packet = (IPv6) ethernet.getPayload();
diff --git a/src/main/java/org/onosproject/segmentrouting/SegmentRoutingNeighbourHandler.java b/src/main/java/org/onosproject/segmentrouting/SegmentRoutingNeighbourHandler.java
index ae32bfc..1d9a2fc 100644
--- a/src/main/java/org/onosproject/segmentrouting/SegmentRoutingNeighbourHandler.java
+++ b/src/main/java/org/onosproject/segmentrouting/SegmentRoutingNeighbourHandler.java
@@ -82,15 +82,17 @@
         byte[] senderIpAddress;
         try {
             senderMacAddress = config.getDeviceMac(deviceId).toBytes();
-            senderIpAddress = config.getRouterIpAddressForASubnetHost(targetAddress.getIp4Address())
-                    .toOctets();
+            if (targetAddress.isIp4()) {
+                senderIpAddress = config.getRouterIpAddressForASubnetHost(targetAddress.getIp4Address())
+                        .toOctets();
+            } else {
+                senderIpAddress = config.getRouterIpAddressForASubnetHost(targetAddress.getIp6Address())
+                        .toOctets();
+            }
         } catch (DeviceConfigNotFoundException e) {
             log.warn(e.getMessage() + " Aborting sendArpRequest.");
             return;
         }
-        /*
-         * FIXME understand how to manage IPv4/IPv6 together.
-         */
         System.arraycopy(senderMacAddress, 0, mac, 0, senderMacAddress.length);
         System.arraycopy(senderIpAddress, 0, ip, 0, senderIpAddress.length);
     }