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