Added IPv6 support to HostMonitor
This fixes ONOS-635 Change-Id: I49cb135af38d54298ba950d5ce1cc110a6f3184d
Showing
1 changed file
with
75 additions
and
16 deletions
| ... | @@ -19,9 +19,14 @@ import org.jboss.netty.util.Timeout; | ... | @@ -19,9 +19,14 @@ import org.jboss.netty.util.Timeout; |
| 19 | import org.jboss.netty.util.TimerTask; | 19 | import org.jboss.netty.util.TimerTask; |
| 20 | import org.onlab.packet.ARP; | 20 | import org.onlab.packet.ARP; |
| 21 | import org.onlab.packet.Ethernet; | 21 | import org.onlab.packet.Ethernet; |
| 22 | +import org.onlab.packet.ICMP6; | ||
| 22 | import org.onlab.packet.IpAddress; | 23 | import org.onlab.packet.IpAddress; |
| 24 | +import org.onlab.packet.Ip4Address; | ||
| 25 | +import org.onlab.packet.IPv6; | ||
| 23 | import org.onlab.packet.MacAddress; | 26 | import org.onlab.packet.MacAddress; |
| 24 | import org.onlab.packet.VlanId; | 27 | import org.onlab.packet.VlanId; |
| 28 | +import org.onlab.packet.ndp.NeighborDiscoveryOptions; | ||
| 29 | +import org.onlab.packet.ndp.NeighborSolicitation; | ||
| 25 | import org.onlab.util.Timer; | 30 | import org.onlab.util.Timer; |
| 26 | import org.onosproject.net.ConnectPoint; | 31 | import org.onosproject.net.ConnectPoint; |
| 27 | import org.onosproject.net.Device; | 32 | import org.onosproject.net.Device; |
| ... | @@ -149,7 +154,7 @@ public class HostMonitor implements TimerTask { | ... | @@ -149,7 +154,7 @@ public class HostMonitor implements TimerTask { |
| 149 | Set<Host> hosts = hostManager.getHostsByIp(ip); | 154 | Set<Host> hosts = hostManager.getHostsByIp(ip); |
| 150 | 155 | ||
| 151 | if (hosts.isEmpty()) { | 156 | if (hosts.isEmpty()) { |
| 152 | - sendArpRequest(ip); | 157 | + sendArpNdpRequest(ip); |
| 153 | } else { | 158 | } else { |
| 154 | for (Host host : hosts) { | 159 | for (Host host : hosts) { |
| 155 | HostProvider provider = hostProviders.get(host.providerId()); | 160 | HostProvider provider = hostProviders.get(host.providerId()); |
| ... | @@ -166,12 +171,13 @@ public class HostMonitor implements TimerTask { | ... | @@ -166,12 +171,13 @@ public class HostMonitor implements TimerTask { |
| 166 | } | 171 | } |
| 167 | 172 | ||
| 168 | /** | 173 | /** |
| 169 | - * Sends an ARP request for the given IP address. | 174 | + * Sends an ARP or Neighbor Discovery Protocol request for the given IP |
| 175 | + * address. | ||
| 170 | * | 176 | * |
| 171 | - * @param targetIp IP address to ARP for | 177 | + * @param targetIp IP address to send the request for |
| 172 | */ | 178 | */ |
| 173 | - private void sendArpRequest(IpAddress targetIp) { | 179 | + private void sendArpNdpRequest(IpAddress targetIp) { |
| 174 | - // Find ports with an IP address in the target's subnet and sent ARP | 180 | + // Find ports with an IP address in the target's subnet and sent ARP/ND |
| 175 | // probes out those ports. | 181 | // probes out those ports. |
| 176 | for (Device device : deviceService.getDevices()) { | 182 | for (Device device : deviceService.getDevices()) { |
| 177 | for (Port port : deviceService.getPorts(device.id())) { | 183 | for (Port port : deviceService.getPorts(device.id())) { |
| ... | @@ -182,9 +188,10 @@ public class HostMonitor implements TimerTask { | ... | @@ -182,9 +188,10 @@ public class HostMonitor implements TimerTask { |
| 182 | for (PortAddresses portAddresses : portAddressSet) { | 188 | for (PortAddresses portAddresses : portAddressSet) { |
| 183 | for (InterfaceIpAddress ia : portAddresses.ipAddresses()) { | 189 | for (InterfaceIpAddress ia : portAddresses.ipAddresses()) { |
| 184 | if (ia.subnetAddress().contains(targetIp)) { | 190 | if (ia.subnetAddress().contains(targetIp)) { |
| 185 | - sendProbe(device.id(), port, targetIp, | 191 | + sendArpNdpProbe(device.id(), port, targetIp, |
| 186 | - ia.ipAddress(), portAddresses.mac(), | 192 | + ia.ipAddress(), |
| 187 | - portAddresses.vlan()); | 193 | + portAddresses.mac(), |
| 194 | + portAddresses.vlan()); | ||
| 188 | } | 195 | } |
| 189 | } | 196 | } |
| 190 | } | 197 | } |
| ... | @@ -192,26 +199,38 @@ public class HostMonitor implements TimerTask { | ... | @@ -192,26 +199,38 @@ public class HostMonitor implements TimerTask { |
| 192 | } | 199 | } |
| 193 | } | 200 | } |
| 194 | 201 | ||
| 195 | - private void sendProbe(DeviceId deviceId, Port port, IpAddress targetIp, | 202 | + private void sendArpNdpProbe(DeviceId deviceId, Port port, |
| 196 | - IpAddress sourceIp, MacAddress sourceMac, VlanId vlan) { | 203 | + IpAddress targetIp, |
| 197 | - Ethernet arpPacket = buildArpRequest(targetIp, sourceIp, sourceMac, vlan); | 204 | + IpAddress sourceIp, MacAddress sourceMac, |
| 205 | + VlanId vlan) { | ||
| 206 | + Ethernet probePacket = null; | ||
| 207 | + | ||
| 208 | + if (targetIp.version() == Ip4Address.VERSION) { | ||
| 209 | + // IPv4: Use ARP | ||
| 210 | + probePacket = buildArpRequest(targetIp, sourceIp, sourceMac, | ||
| 211 | + vlan); | ||
| 212 | + } else { | ||
| 213 | + // IPv6: Use Neighbor Discovery | ||
| 214 | + probePacket = buildNdpRequest(targetIp, sourceIp, sourceMac, | ||
| 215 | + vlan); | ||
| 216 | + } | ||
| 198 | 217 | ||
| 199 | List<Instruction> instructions = new ArrayList<>(); | 218 | List<Instruction> instructions = new ArrayList<>(); |
| 200 | instructions.add(Instructions.createOutput(port.number())); | 219 | instructions.add(Instructions.createOutput(port.number())); |
| 201 | 220 | ||
| 202 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 221 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
| 203 | - .setOutput(port.number()) | 222 | + .setOutput(port.number()) |
| 204 | - .build(); | 223 | + .build(); |
| 205 | 224 | ||
| 206 | OutboundPacket outboundPacket = | 225 | OutboundPacket outboundPacket = |
| 207 | - new DefaultOutboundPacket(deviceId, treatment, | 226 | + new DefaultOutboundPacket(deviceId, treatment, |
| 208 | - ByteBuffer.wrap(arpPacket.serialize())); | 227 | + ByteBuffer.wrap(probePacket.serialize())); |
| 209 | 228 | ||
| 210 | packetService.emit(outboundPacket); | 229 | packetService.emit(outboundPacket); |
| 211 | } | 230 | } |
| 212 | 231 | ||
| 213 | private Ethernet buildArpRequest(IpAddress targetIp, IpAddress sourceIp, | 232 | private Ethernet buildArpRequest(IpAddress targetIp, IpAddress sourceIp, |
| 214 | - MacAddress sourceMac, VlanId vlan) { | 233 | + MacAddress sourceMac, VlanId vlan) { |
| 215 | 234 | ||
| 216 | ARP arp = new ARP(); | 235 | ARP arp = new ARP(); |
| 217 | arp.setHardwareType(ARP.HW_TYPE_ETHERNET) | 236 | arp.setHardwareType(ARP.HW_TYPE_ETHERNET) |
| ... | @@ -237,4 +256,44 @@ public class HostMonitor implements TimerTask { | ... | @@ -237,4 +256,44 @@ public class HostMonitor implements TimerTask { |
| 237 | 256 | ||
| 238 | return ethernet; | 257 | return ethernet; |
| 239 | } | 258 | } |
| 259 | + | ||
| 260 | + private Ethernet buildNdpRequest(IpAddress targetIp, IpAddress sourceIp, | ||
| 261 | + MacAddress sourceMac, VlanId vlan) { | ||
| 262 | + | ||
| 263 | + // Create the Ethernet packet | ||
| 264 | + Ethernet ethernet = new Ethernet(); | ||
| 265 | + ethernet.setEtherType(Ethernet.TYPE_IPV6) | ||
| 266 | + .setDestinationMACAddress(MacAddress.BROADCAST) | ||
| 267 | + .setSourceMACAddress(sourceMac); | ||
| 268 | + if (!vlan.equals(VlanId.NONE)) { | ||
| 269 | + ethernet.setVlanID(vlan.toShort()); | ||
| 270 | + } | ||
| 271 | + | ||
| 272 | + // | ||
| 273 | + // Create the IPv6 packet | ||
| 274 | + // | ||
| 275 | + // TODO: The destination IP address should be the | ||
| 276 | + // solicited-node multicast address | ||
| 277 | + IPv6 ipv6 = new IPv6(); | ||
| 278 | + ipv6.setSourceAddress(sourceIp.toOctets()); | ||
| 279 | + ipv6.setDestinationAddress(targetIp.toOctets()); | ||
| 280 | + ipv6.setHopLimit((byte) 255); | ||
| 281 | + | ||
| 282 | + // Create the ICMPv6 packet | ||
| 283 | + ICMP6 icmp6 = new ICMP6(); | ||
| 284 | + icmp6.setIcmpType(ICMP6.NEIGHBOR_SOLICITATION); | ||
| 285 | + icmp6.setIcmpCode((byte) 0); | ||
| 286 | + | ||
| 287 | + // Create the Neighbor Solication packet | ||
| 288 | + NeighborSolicitation ns = new NeighborSolicitation(); | ||
| 289 | + ns.setTargetAddress(targetIp.toOctets()); | ||
| 290 | + ns.addOption(NeighborDiscoveryOptions.TYPE_SOURCE_LL_ADDRESS, | ||
| 291 | + sourceMac.toBytes()); | ||
| 292 | + | ||
| 293 | + icmp6.setPayload(ns); | ||
| 294 | + ipv6.setPayload(icmp6); | ||
| 295 | + ethernet.setPayload(ipv6); | ||
| 296 | + | ||
| 297 | + return ethernet; | ||
| 298 | + } | ||
| 240 | } | 299 | } | ... | ... |
-
Please register or login to post a comment