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