Implemented HostMonitor for probing IP addresses to detect hosts
Showing
1 changed file
with
104 additions
and
23 deletions
| 1 | package org.onlab.onos.net.host.impl; | 1 | package org.onlab.onos.net.host.impl; |
| 2 | 2 | ||
| 3 | +import java.nio.ByteBuffer; | ||
| 4 | +import java.util.ArrayList; | ||
| 5 | +import java.util.Collections; | ||
| 3 | import java.util.HashSet; | 6 | import java.util.HashSet; |
| 7 | +import java.util.List; | ||
| 4 | import java.util.Set; | 8 | import java.util.Set; |
| 5 | import java.util.concurrent.TimeUnit; | 9 | import java.util.concurrent.TimeUnit; |
| 6 | 10 | ||
| 7 | import org.jboss.netty.util.Timeout; | 11 | import org.jboss.netty.util.Timeout; |
| 8 | import org.jboss.netty.util.TimerTask; | 12 | import org.jboss.netty.util.TimerTask; |
| 13 | +import org.onlab.onos.net.ConnectPoint; | ||
| 14 | +import org.onlab.onos.net.Device; | ||
| 15 | +import org.onlab.onos.net.DeviceId; | ||
| 9 | import org.onlab.onos.net.Host; | 16 | import org.onlab.onos.net.Host; |
| 10 | import org.onlab.onos.net.Port; | 17 | import org.onlab.onos.net.Port; |
| 11 | import org.onlab.onos.net.device.DeviceService; | 18 | import org.onlab.onos.net.device.DeviceService; |
| 19 | +import org.onlab.onos.net.flow.DefaultTrafficTreatment; | ||
| 20 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
| 21 | +import org.onlab.onos.net.flow.instructions.Instruction; | ||
| 22 | +import org.onlab.onos.net.flow.instructions.Instructions; | ||
| 12 | import org.onlab.onos.net.host.HostProvider; | 23 | import org.onlab.onos.net.host.HostProvider; |
| 13 | import org.onlab.onos.net.host.HostService; | 24 | import org.onlab.onos.net.host.HostService; |
| 14 | -import org.onlab.onos.net.packet.PacketProvider; | 25 | +import org.onlab.onos.net.host.HostStore; |
| 26 | +import org.onlab.onos.net.host.PortAddresses; | ||
| 27 | +import org.onlab.onos.net.packet.DefaultOutboundPacket; | ||
| 28 | +import org.onlab.onos.net.packet.OutboundPacket; | ||
| 29 | +import org.onlab.onos.net.packet.PacketService; | ||
| 15 | import org.onlab.onos.net.topology.TopologyService; | 30 | import org.onlab.onos.net.topology.TopologyService; |
| 31 | +import org.onlab.packet.ARP; | ||
| 32 | +import org.onlab.packet.Ethernet; | ||
| 33 | +import org.onlab.packet.IpAddress; | ||
| 16 | import org.onlab.packet.IpPrefix; | 34 | import org.onlab.packet.IpPrefix; |
| 35 | +import org.onlab.packet.MacAddress; | ||
| 17 | import org.onlab.util.Timer; | 36 | import org.onlab.util.Timer; |
| 18 | 37 | ||
| 38 | +/** | ||
| 39 | + * Monitors hosts on the dataplane to detect changes in host data. | ||
| 40 | + * <p/> | ||
| 41 | + * The HostMonitor can monitor hosts that have already been detected for | ||
| 42 | + * changes. At an application's request, it can also monitor and actively | ||
| 43 | + * probe for hosts that have not yet been detected (specified by IP address). | ||
| 44 | + */ | ||
| 19 | public class HostMonitor implements TimerTask { | 45 | public class HostMonitor implements TimerTask { |
| 20 | 46 | ||
| 47 | + private static final byte[] DEFAULT_MAC_ADDRESS = | ||
| 48 | + MacAddress.valueOf("00:00:00:00:00:01").getAddress(); | ||
| 49 | + | ||
| 50 | + private static final byte[] ZERO_MAC_ADDRESS = | ||
| 51 | + MacAddress.valueOf("00:00:00:00:00:00").getAddress(); | ||
| 52 | + | ||
| 53 | + // TODO put on Ethernet | ||
| 54 | + private static final byte[] BROADCAST_MAC = | ||
| 55 | + MacAddress.valueOf("ff:ff:ff:ff:ff:ff").getAddress(); | ||
| 56 | + | ||
| 21 | private final HostService hostService; | 57 | private final HostService hostService; |
| 22 | private final TopologyService topologyService; | 58 | private final TopologyService topologyService; |
| 23 | private final DeviceService deviceService; | 59 | private final DeviceService deviceService; |
| 24 | private final HostProvider hostProvider; | 60 | private final HostProvider hostProvider; |
| 25 | - private final PacketProvider packetProvider; | 61 | + private final PacketService packetService; |
| 62 | + private final HostStore hostStore; | ||
| 26 | 63 | ||
| 27 | - private final Set<IpPrefix> monitoredAddresses; | 64 | + private final Set<IpAddress> monitoredAddresses; |
| 28 | 65 | ||
| 29 | private final long probeRate; | 66 | private final long probeRate; |
| 30 | 67 | ||
| ... | @@ -32,12 +69,14 @@ public class HostMonitor implements TimerTask { | ... | @@ -32,12 +69,14 @@ public class HostMonitor implements TimerTask { |
| 32 | 69 | ||
| 33 | public HostMonitor(HostService hostService, TopologyService topologyService, | 70 | public HostMonitor(HostService hostService, TopologyService topologyService, |
| 34 | DeviceService deviceService, | 71 | DeviceService deviceService, |
| 35 | - HostProvider hostProvider, PacketProvider packetProvider) { | 72 | + HostProvider hostProvider, PacketService packetService, |
| 73 | + HostStore hostStore) { | ||
| 36 | this.hostService = hostService; | 74 | this.hostService = hostService; |
| 37 | this.topologyService = topologyService; | 75 | this.topologyService = topologyService; |
| 38 | this.deviceService = deviceService; | 76 | this.deviceService = deviceService; |
| 39 | this.hostProvider = hostProvider; | 77 | this.hostProvider = hostProvider; |
| 40 | - this.packetProvider = packetProvider; | 78 | + this.packetService = packetService; |
| 79 | + this.hostStore = hostStore; | ||
| 41 | 80 | ||
| 42 | monitoredAddresses = new HashSet<>(); | 81 | monitoredAddresses = new HashSet<>(); |
| 43 | 82 | ||
| ... | @@ -46,11 +85,11 @@ public class HostMonitor implements TimerTask { | ... | @@ -46,11 +85,11 @@ public class HostMonitor implements TimerTask { |
| 46 | timeout = Timer.getTimer().newTimeout(this, 0, TimeUnit.MILLISECONDS); | 85 | timeout = Timer.getTimer().newTimeout(this, 0, TimeUnit.MILLISECONDS); |
| 47 | } | 86 | } |
| 48 | 87 | ||
| 49 | - public void addMonitoringFor(IpPrefix ip) { | 88 | + public void addMonitoringFor(IpAddress ip) { |
| 50 | monitoredAddresses.add(ip); | 89 | monitoredAddresses.add(ip); |
| 51 | } | 90 | } |
| 52 | 91 | ||
| 53 | - public void stopMonitoring(IpPrefix ip) { | 92 | + public void stopMonitoring(IpAddress ip) { |
| 54 | monitoredAddresses.remove(ip); | 93 | monitoredAddresses.remove(ip); |
| 55 | } | 94 | } |
| 56 | 95 | ||
| ... | @@ -60,8 +99,8 @@ public class HostMonitor implements TimerTask { | ... | @@ -60,8 +99,8 @@ public class HostMonitor implements TimerTask { |
| 60 | 99 | ||
| 61 | @Override | 100 | @Override |
| 62 | public void run(Timeout timeout) throws Exception { | 101 | public void run(Timeout timeout) throws Exception { |
| 63 | - for (IpPrefix ip : monitoredAddresses) { | 102 | + for (IpAddress ip : monitoredAddresses) { |
| 64 | - Set<Host> hosts = hostService.getHostsByIp(ip); | 103 | + Set<Host> hosts = Collections.emptySet(); //TODO hostService.getHostsByIp(ip); |
| 65 | 104 | ||
| 66 | if (hosts.isEmpty()) { | 105 | if (hosts.isEmpty()) { |
| 67 | sendArpRequest(ip); | 106 | sendArpRequest(ip); |
| ... | @@ -80,28 +119,70 @@ public class HostMonitor implements TimerTask { | ... | @@ -80,28 +119,70 @@ public class HostMonitor implements TimerTask { |
| 80 | * | 119 | * |
| 81 | * @param targetIp IP address to ARP for | 120 | * @param targetIp IP address to ARP for |
| 82 | */ | 121 | */ |
| 83 | - private void sendArpRequest(IpPrefix targetIp) { | 122 | + private void sendArpRequest(IpAddress targetIp) { |
| 84 | - // emit ARP packet out appropriate ports | ||
| 85 | - | ||
| 86 | - // if ip in one of the configured (external) subnets | ||
| 87 | - // sent out that port | ||
| 88 | - // else (ip isn't in any configured subnet) | ||
| 89 | - // send out all non-external edge ports | ||
| 90 | 123 | ||
| 91 | - /*for (Device device : deviceService.getDevices()) { | 124 | + // Find ports with an IP address in the target's subnet and sent ARP |
| 125 | + // probes out those ports. | ||
| 126 | + for (Device device : deviceService.getDevices()) { | ||
| 92 | for (Port port : deviceService.getPorts(device.id())) { | 127 | for (Port port : deviceService.getPorts(device.id())) { |
| 93 | - for (IpPrefix ip : port.ipAddresses()) { | 128 | + ConnectPoint cp = new ConnectPoint(device.id(), port.number()); |
| 94 | - if (ip.contains(targetIp)) { | 129 | + PortAddresses addresses = hostStore.getAddressBindingsForPort(cp); |
| 95 | - sendProbe(port, targetIp); | 130 | + |
| 96 | - continue; | 131 | + if (addresses.ip().contains(targetIp)) { |
| 132 | + sendProbe(device.id(), port, addresses, targetIp); | ||
| 133 | + } | ||
| 97 | } | 134 | } |
| 98 | } | 135 | } |
| 136 | + | ||
| 137 | + // TODO case where no address was found. | ||
| 138 | + // Broadcast out internal edge ports? | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + private void sendProbe(DeviceId deviceId, Port port, PortAddresses portAddresses, | ||
| 142 | + IpAddress targetIp) { | ||
| 143 | + Ethernet arpPacket = createArpFor(targetIp, portAddresses); | ||
| 144 | + | ||
| 145 | + List<Instruction> instructions = new ArrayList<>(); | ||
| 146 | + instructions.add(Instructions.createOutput(port.number())); | ||
| 147 | + | ||
| 148 | + TrafficTreatment treatment = | ||
| 149 | + new DefaultTrafficTreatment.Builder() | ||
| 150 | + .add(Instructions.createOutput(port.number())) | ||
| 151 | + .build(); | ||
| 152 | + | ||
| 153 | + OutboundPacket outboundPacket = | ||
| 154 | + new DefaultOutboundPacket(deviceId, treatment, | ||
| 155 | + ByteBuffer.wrap(arpPacket.serialize())); | ||
| 156 | + | ||
| 157 | + packetService.emit(outboundPacket); | ||
| 99 | } | 158 | } |
| 100 | - }*/ | ||
| 101 | 159 | ||
| 160 | + private Ethernet createArpFor(IpAddress targetIp, PortAddresses portAddresses) { | ||
| 161 | + | ||
| 162 | + ARP arp = new ARP(); | ||
| 163 | + arp.setHardwareType(ARP.HW_TYPE_ETHERNET) | ||
| 164 | + .setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH) | ||
| 165 | + .setProtocolType(ARP.PROTO_TYPE_IP) | ||
| 166 | + .setProtocolAddressLength((byte) IpPrefix.INET_LEN); | ||
| 167 | + | ||
| 168 | + byte[] sourceMacAddress; | ||
| 169 | + if (portAddresses.mac() == null) { | ||
| 170 | + sourceMacAddress = DEFAULT_MAC_ADDRESS; | ||
| 171 | + } else { | ||
| 172 | + sourceMacAddress = portAddresses.mac().getAddress(); | ||
| 102 | } | 173 | } |
| 103 | 174 | ||
| 104 | - private void sendProbe(Port port, IpPrefix targetIp) { | 175 | + arp.setSenderHardwareAddress(sourceMacAddress) |
| 176 | + .setSenderProtocolAddress(portAddresses.ip().toOctets()) | ||
| 177 | + .setTargetHardwareAddress(ZERO_MAC_ADDRESS) | ||
| 178 | + .setTargetProtocolAddress(targetIp.toOctets()); | ||
| 179 | + | ||
| 180 | + Ethernet ethernet = new Ethernet(); | ||
| 181 | + ethernet.setEtherType(Ethernet.TYPE_ARP) | ||
| 182 | + .setDestinationMACAddress(BROADCAST_MAC) | ||
| 183 | + .setSourceMACAddress(sourceMacAddress) | ||
| 184 | + .setPayload(arp); | ||
| 105 | 185 | ||
| 186 | + return ethernet; | ||
| 106 | } | 187 | } |
| 107 | } | 188 | } | ... | ... |
-
Please register or login to post a comment