ONOS-1414: Fix phantom hosts
- Refactor HostLocationProvider - Ignore multicast packets other than NDP Change-Id: I6b66becbc30a6a7e83f1da53fb46cf9c073fc86c
Showing
1 changed file
with
63 additions
and
29 deletions
... | @@ -28,7 +28,9 @@ import org.onlab.packet.ICMP6; | ... | @@ -28,7 +28,9 @@ import org.onlab.packet.ICMP6; |
28 | import org.onlab.packet.IPacket; | 28 | import org.onlab.packet.IPacket; |
29 | import org.onlab.packet.IPv6; | 29 | import org.onlab.packet.IPv6; |
30 | import org.onlab.packet.IpAddress; | 30 | import org.onlab.packet.IpAddress; |
31 | +import org.onlab.packet.MacAddress; | ||
31 | import org.onlab.packet.VlanId; | 32 | import org.onlab.packet.VlanId; |
33 | +import org.onlab.packet.ipv6.IExtensionHeader; | ||
32 | import org.onlab.packet.ndp.NeighborAdvertisement; | 34 | import org.onlab.packet.ndp.NeighborAdvertisement; |
33 | import org.onlab.packet.ndp.NeighborSolicitation; | 35 | import org.onlab.packet.ndp.NeighborSolicitation; |
34 | import org.onlab.packet.ndp.RouterAdvertisement; | 36 | import org.onlab.packet.ndp.RouterAdvertisement; |
... | @@ -230,6 +232,34 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid | ... | @@ -230,6 +232,34 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid |
230 | } | 232 | } |
231 | 233 | ||
232 | private class InternalHostProvider implements PacketProcessor { | 234 | private class InternalHostProvider implements PacketProcessor { |
235 | + /** | ||
236 | + * Update host location only. | ||
237 | + * | ||
238 | + * @param hid host ID | ||
239 | + * @param mac source Mac address | ||
240 | + * @param vlan VLAN ID | ||
241 | + * @param hloc host location | ||
242 | + */ | ||
243 | + private void updateLocation(HostId hid, MacAddress mac, | ||
244 | + VlanId vlan, HostLocation hloc) { | ||
245 | + HostDescription desc = new DefaultHostDescription(mac, vlan, hloc); | ||
246 | + providerService.hostDetected(hid, desc); | ||
247 | + } | ||
248 | + /** | ||
249 | + * Update host location and IP address. | ||
250 | + * | ||
251 | + * @param hid host ID | ||
252 | + * @param mac source Mac address | ||
253 | + * @param vlan VLAN ID | ||
254 | + * @param hloc host location | ||
255 | + * @param ip source IP address | ||
256 | + */ | ||
257 | + private void updateLocationIP(HostId hid, MacAddress mac, | ||
258 | + VlanId vlan, HostLocation hloc, | ||
259 | + IpAddress ip) { | ||
260 | + HostDescription desc = new DefaultHostDescription(mac, vlan, hloc, ip); | ||
261 | + providerService.hostDetected(hid, desc); | ||
262 | + } | ||
233 | 263 | ||
234 | @Override | 264 | @Override |
235 | public void process(PacketContext context) { | 265 | public void process(PacketContext context) { |
... | @@ -241,6 +271,7 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid | ... | @@ -241,6 +271,7 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid |
241 | if (eth == null) { | 271 | if (eth == null) { |
242 | return; | 272 | return; |
243 | } | 273 | } |
274 | + MacAddress srcMac = eth.getSourceMAC(); | ||
244 | 275 | ||
245 | VlanId vlan = VlanId.vlanId(eth.getVlanID()); | 276 | VlanId vlan = VlanId.vlanId(eth.getVlanID()); |
246 | ConnectPoint heardOn = context.inPacket().receivedFrom(); | 277 | ConnectPoint heardOn = context.inPacket().receivedFrom(); |
... | @@ -266,16 +297,11 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid | ... | @@ -266,16 +297,11 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid |
266 | ARP arp = (ARP) eth.getPayload(); | 297 | ARP arp = (ARP) eth.getPayload(); |
267 | IpAddress ip = IpAddress.valueOf(IpAddress.Version.INET, | 298 | IpAddress ip = IpAddress.valueOf(IpAddress.Version.INET, |
268 | arp.getSenderProtocolAddress()); | 299 | arp.getSenderProtocolAddress()); |
269 | - HostDescription hdescr = | 300 | + updateLocationIP(hid, srcMac, vlan, hloc, ip); |
270 | - new DefaultHostDescription(eth.getSourceMAC(), vlan, | ||
271 | - hloc, ip); | ||
272 | - providerService.hostDetected(hid, hdescr); | ||
273 | 301 | ||
274 | // IPv4: update location only | 302 | // IPv4: update location only |
275 | } else if (eth.getEtherType() == Ethernet.TYPE_IPV4) { | 303 | } else if (eth.getEtherType() == Ethernet.TYPE_IPV4) { |
276 | - HostDescription hdescr = | 304 | + updateLocation(hid, srcMac, vlan, hloc); |
277 | - new DefaultHostDescription(eth.getSourceMAC(), vlan, hloc); | ||
278 | - providerService.hostDetected(hid, hdescr); | ||
279 | 305 | ||
280 | // | 306 | // |
281 | // NeighborAdvertisement and NeighborSolicitation: possible | 307 | // NeighborAdvertisement and NeighborSolicitation: possible |
... | @@ -283,36 +309,44 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid | ... | @@ -283,36 +309,44 @@ public class HostLocationProvider extends AbstractProvider implements HostProvid |
283 | // | 309 | // |
284 | // IPv6: update location only | 310 | // IPv6: update location only |
285 | } else if (eth.getEtherType() == Ethernet.TYPE_IPV6) { | 311 | } else if (eth.getEtherType() == Ethernet.TYPE_IPV6) { |
286 | - IpAddress ip = null; | ||
287 | IPv6 ipv6 = (IPv6) eth.getPayload(); | 312 | IPv6 ipv6 = (IPv6) eth.getPayload(); |
313 | + IpAddress ip = IpAddress.valueOf(IpAddress.Version.INET6, | ||
314 | + ipv6.getSourceAddress()); | ||
315 | + | ||
316 | + // skip extension headers | ||
317 | + IPacket pkt = ipv6; | ||
318 | + while (pkt.getPayload() != null && | ||
319 | + pkt.getPayload() instanceof IExtensionHeader) { | ||
320 | + pkt = pkt.getPayload(); | ||
321 | + } | ||
288 | 322 | ||
289 | - IPacket iPkt = ipv6; | 323 | + // Neighbor Discovery Protocol |
290 | - while (iPkt != null) { | 324 | + if (pkt instanceof ICMP6) { |
291 | - // Ignore Router Solicitation and Advertisement | 325 | + pkt = pkt.getPayload(); |
292 | - if (iPkt instanceof RouterAdvertisement || | 326 | + // RouterSolicitation, RouterAdvertisement |
293 | - iPkt instanceof RouterSolicitation) { | 327 | + if (pkt instanceof RouterAdvertisement || |
328 | + pkt instanceof RouterSolicitation) { | ||
294 | return; | 329 | return; |
295 | } | 330 | } |
296 | - if (iPkt instanceof NeighborAdvertisement || | 331 | + if (pkt instanceof NeighborSolicitation || |
297 | - iPkt instanceof NeighborSolicitation) { | 332 | + pkt instanceof NeighborAdvertisement) { |
298 | - IpAddress sourceAddress = | 333 | + // Duplicate Address Detection |
299 | - IpAddress.valueOf(IpAddress.Version.INET6, | 334 | + if (ip.isZero()) { |
300 | - ipv6.getSourceAddress()); | ||
301 | - // Ignore DAD packets, in which source address is zero | ||
302 | - if (sourceAddress.isZero()) { | ||
303 | return; | 335 | return; |
304 | } | 336 | } |
305 | - ip = sourceAddress; | 337 | + // NeighborSolicitation, NeighborAdvertisement |
306 | - break; | 338 | + updateLocationIP(hid, srcMac, vlan, hloc, ip); |
339 | + return; | ||
307 | } | 340 | } |
308 | - iPkt = iPkt.getPayload(); | ||
309 | } | 341 | } |
310 | - HostDescription hdescr = (ip == null) ? | 342 | + |
311 | - new DefaultHostDescription(eth.getSourceMAC(), vlan, | 343 | + // multicast |
312 | - hloc) : | 344 | + if (eth.isMulticast()) { |
313 | - new DefaultHostDescription(eth.getSourceMAC(), vlan, | 345 | + return; |
314 | - hloc, ip); | 346 | + } |
315 | - providerService.hostDetected(hid, hdescr); | 347 | + |
348 | + // normal IPv6 packets | ||
349 | + updateLocation(hid, srcMac, vlan, hloc); | ||
316 | } | 350 | } |
317 | } | 351 | } |
318 | } | 352 | } | ... | ... |
-
Please register or login to post a comment