blob: e555ab5bffe62c73a5359a206e5b05482924172a [file] [log] [blame]
Jonathan Hart03102132014-07-01 23:22:04 -07001package net.onrc.onos.core.hostmanager;
Jonathan Hartd857ad62013-12-14 18:08:17 -08002
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.Date;
6import java.util.HashMap;
TeruU80ce5062014-03-03 17:16:13 -08007import java.util.HashSet;
Jonathan Hartd857ad62013-12-14 18:08:17 -08008import java.util.List;
9import java.util.Map;
TeruU80ce5062014-03-03 17:16:13 -080010import java.util.Set;
TeruUd1c5b652014-03-24 13:58:46 -070011import java.util.concurrent.CopyOnWriteArrayList;
TeruU80ce5062014-03-03 17:16:13 -080012import java.util.concurrent.Executors;
13import java.util.concurrent.ScheduledExecutorService;
14import java.util.concurrent.TimeUnit;
Jonathan Hartd857ad62013-12-14 18:08:17 -080015
16import net.floodlightcontroller.core.FloodlightContext;
17import net.floodlightcontroller.core.IFloodlightProviderService;
18import net.floodlightcontroller.core.IOFMessageListener;
19import net.floodlightcontroller.core.IOFSwitch;
20import net.floodlightcontroller.core.IUpdate;
21import net.floodlightcontroller.core.module.FloodlightModuleContext;
22import net.floodlightcontroller.core.module.FloodlightModuleException;
23import net.floodlightcontroller.core.module.IFloodlightModule;
24import net.floodlightcontroller.core.module.IFloodlightService;
Jonathan Hartd857ad62013-12-14 18:08:17 -080025import net.floodlightcontroller.util.MACAddress;
Sangho Shin2f263692014-09-15 14:09:41 -070026import net.onrc.onos.core.packet.ARP;
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070027import net.onrc.onos.core.packet.Ethernet;
Sangho Shin2f263692014-09-15 14:09:41 -070028import net.onrc.onos.core.packet.IPv4;
Jonathan Harte37e4e22014-05-13 19:12:02 -070029import net.onrc.onos.core.topology.ITopologyService;
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -070030import net.onrc.onos.core.topology.MutableTopology;
Sangho Shin2f263692014-09-15 14:09:41 -070031import net.onrc.onos.core.topology.Port;
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -070032import net.onrc.onos.core.util.Dpid;
33import net.onrc.onos.core.util.PortNumber;
Yuta HIGUCHIa507baf2014-08-22 13:42:40 -070034import net.onrc.onos.core.util.PortNumberUtils;
Jonathan Hartd857ad62013-12-14 18:08:17 -080035
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070036import org.projectfloodlight.openflow.protocol.OFMessage;
37import org.projectfloodlight.openflow.protocol.OFPacketIn;
38import org.projectfloodlight.openflow.protocol.OFType;
Sangho Shin2f263692014-09-15 14:09:41 -070039import org.projectfloodlight.openflow.types.IPv4Address;
TeruU80ce5062014-03-03 17:16:13 -080040import org.slf4j.Logger;
41import org.slf4j.LoggerFactory;
Jonathan Hartd857ad62013-12-14 18:08:17 -080042
Jonathan Hart03102132014-07-01 23:22:04 -070043public class HostManager implements IFloodlightModule,
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070044IOFMessageListener,
45IHostService {
TeruU28adcc32014-04-15 17:57:35 -070046
Jonathan Hart03102132014-07-01 23:22:04 -070047 private static final Logger log = LoggerFactory.getLogger(HostManager.class);
48 private static final long HOST_CLEANING_INITIAL_DELAY = 30;
TeruU28adcc32014-04-15 17:57:35 -070049 private int cleanupSecondConfig = 60 * 60;
50 private int agingMillisecConfig = 60 * 60 * 1000;
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -070051
Jonathan Hart03102132014-07-01 23:22:04 -070052 private CopyOnWriteArrayList<IHostListener> hostListeners;
Ray Milkey269ffb92014-04-03 14:43:30 -070053 private IFloodlightProviderService floodlightProvider;
Jonathan Hart83ce8c42014-06-02 00:07:06 -070054 private static final ScheduledExecutorService EXECUTOR_SERVICE =
55 Executors.newSingleThreadScheduledExecutor();
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -070056
Jonathan Harte37e4e22014-05-13 19:12:02 -070057 private ITopologyService topologyService;
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -070058 private MutableTopology mutableTopology;
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -070059
Jonathan Hart03102132014-07-01 23:22:04 -070060 public enum HostUpdateType {
TeruU80ce5062014-03-03 17:16:13 -080061 ADD, DELETE, UPDATE;
62 }
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -070063
Jonathan Hart03102132014-07-01 23:22:04 -070064 private class HostUpdate implements IUpdate {
65 private final Host host;
66 private final HostUpdateType type;
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -070067
Jonathan Hart03102132014-07-01 23:22:04 -070068 public HostUpdate(Host host, HostUpdateType type) {
69 this.host = host;
Ray Milkey269ffb92014-04-03 14:43:30 -070070 this.type = type;
71 }
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -070072
Ray Milkey269ffb92014-04-03 14:43:30 -070073 @Override
74 public void dispatch() {
Jonathan Hart03102132014-07-01 23:22:04 -070075 if (type == HostUpdateType.ADD) {
76 for (IHostListener listener : hostListeners) {
77 listener.hostAdded(host);
Ray Milkey269ffb92014-04-03 14:43:30 -070078 }
Jonathan Hart03102132014-07-01 23:22:04 -070079 } else if (type == HostUpdateType.DELETE) {
80 for (IHostListener listener : hostListeners) {
81 listener.hostRemoved(host);
Ray Milkey269ffb92014-04-03 14:43:30 -070082 }
83 }
84 }
85 }
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -070086
Ray Milkey269ffb92014-04-03 14:43:30 -070087 @Override
88 public String getName() {
Jonathan Hart03102132014-07-01 23:22:04 -070089 return "hostmanager";
Ray Milkey269ffb92014-04-03 14:43:30 -070090 }
Jonathan Hartd857ad62013-12-14 18:08:17 -080091
Ray Milkey269ffb92014-04-03 14:43:30 -070092 @Override
93 public boolean isCallbackOrderingPrereq(OFType type, String name) {
94 // We want link discovery to consume LLDP first otherwise we'll
Jonathan Hart03102132014-07-01 23:22:04 -070095 // end up reading bad host info from LLDP packets
Ray Milkey269ffb92014-04-03 14:43:30 -070096 return type == OFType.PACKET_IN && "linkdiscovery".equals(name);
97 }
Jonathan Hartd857ad62013-12-14 18:08:17 -080098
Ray Milkey269ffb92014-04-03 14:43:30 -070099 @Override
100 public boolean isCallbackOrderingPostreq(OFType type, String name) {
101 return type == OFType.PACKET_IN &&
102 ("proxyarpmanager".equals(name) || "onosforwarding".equals(name));
103 }
Jonathan Hartd857ad62013-12-14 18:08:17 -0800104
Ray Milkey269ffb92014-04-03 14:43:30 -0700105 @Override
106 public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
Pavlin Radoslavov0b88a262014-04-10 15:43:27 -0700107 if (msg.getType().equals(OFType.PACKET_IN) &&
Patrick Liuab1e6062014-05-05 11:12:13 -0700108 (msg instanceof OFPacketIn)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700109 OFPacketIn pi = (OFPacketIn) msg;
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -0700110
Ray Milkey269ffb92014-04-03 14:43:30 -0700111 Ethernet eth = IFloodlightProviderService.bcStore.
112 get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700113 short inport = (short) cntx.getStorage()
114 .get(IFloodlightProviderService.CONTEXT_PI_INPORT);
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -0700115
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700116 return processPacketIn(sw, pi, eth, inport);
Ray Milkey269ffb92014-04-03 14:43:30 -0700117 }
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -0700118
Ray Milkey269ffb92014-04-03 14:43:30 -0700119 return Command.CONTINUE;
120 }
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -0700121
Jonathan Hart83ce8c42014-06-02 00:07:06 -0700122 // This "protected" modifier is for unit test.
123 // The above "receive" method couldn't be tested
124 // because of IFloodlightProviderService static final field.
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700125 protected Command processPacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth,
126 short inport) {
TeruU5d2c9392014-06-09 20:02:02 -0700127 if (log.isTraceEnabled()) {
Yuta HIGUCHIa507baf2014-08-22 13:42:40 -0700128 log.trace("Receive PACKET_IN swId {}, portId {}", sw.getId(), inport);
TeruU5d2c9392014-06-09 20:02:02 -0700129 }
130
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700131 final Dpid dpid = new Dpid(sw.getId());
Yuta HIGUCHIa507baf2014-08-22 13:42:40 -0700132 // FIXME method signature needs to be fixed. losing port number precision
133 final PortNumber portNum = PortNumberUtils
134 .openFlow(sw.getOFVersion(), inport);
TeruU80ce5062014-03-03 17:16:13 -0800135
Jonathan Hart03102132014-07-01 23:22:04 -0700136 Host srcHost =
137 getSourceHostFromPacket(eth, dpid.value(), portNum.value());
TeruU80ce5062014-03-03 17:16:13 -0800138
Jonathan Hart03102132014-07-01 23:22:04 -0700139 if (srcHost == null) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700140 return Command.STOP;
TeruU80ce5062014-03-03 17:16:13 -0800141 }
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -0700142
Jonathan Hart03102132014-07-01 23:22:04 -0700143 // If the switch port we try to attach a new host already has a link,
144 // then don't add the host
Jonathan Hart83ce8c42014-06-02 00:07:06 -0700145 // TODO We probably don't need to check this here, it should be done in
146 // the Topology module.
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -0700147 mutableTopology.acquireReadLock();
TeruU5d2c9392014-06-09 20:02:02 -0700148 try {
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -0700149 if (mutableTopology.getOutgoingLink(dpid, portNum) != null ||
150 mutableTopology.getIncomingLink(dpid, portNum) != null) {
Jonathan Hart03102132014-07-01 23:22:04 -0700151 log.debug("Not adding host {} as " +
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700152 "there is a link on the port: dpid {} port {}",
153 srcHost.getMacAddress(), dpid, portNum);
TeruU5d2c9392014-06-09 20:02:02 -0700154 return Command.CONTINUE;
Ray Milkey269ffb92014-04-03 14:43:30 -0700155 }
TeruU5d2c9392014-06-09 20:02:02 -0700156 } finally {
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -0700157 mutableTopology.releaseReadLock();
TeruU80ce5062014-03-03 17:16:13 -0800158 }
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -0700159
Ray Milkey92897212014-07-21 10:33:16 -0700160 Long mac = eth.getSourceMAC().toLong();
Jonathan Hart03102132014-07-01 23:22:04 -0700161 addHost(mac, srcHost);
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -0700162
Ray Milkey269ffb92014-04-03 14:43:30 -0700163 if (log.isTraceEnabled()) {
Jonathan Hart03102132014-07-01 23:22:04 -0700164 log.trace("Add host info: {}", srcHost);
TeruU80ce5062014-03-03 17:16:13 -0800165 }
Jonathan Hartd857ad62013-12-14 18:08:17 -0800166 return Command.CONTINUE;
Ray Milkey269ffb92014-04-03 14:43:30 -0700167 }
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -0700168
Jonathan Hart03102132014-07-01 23:22:04 -0700169 // Thread to delete hosts periodically.
170 // Remove all hosts from the map first and then finally delete hosts
Jonathan Hart83ce8c42014-06-02 00:07:06 -0700171 // from the DB.
172
Jonathan Hart03102132014-07-01 23:22:04 -0700173 // TODO This should be sharded based on host 'owner' (i.e. the instance
Jonathan Hart83ce8c42014-06-02 00:07:06 -0700174 // that owns the switch it is attached to). Currently any instance can
Jonathan Hart03102132014-07-01 23:22:04 -0700175 // issue deletes for any host, which permits race conditions and could
Jonathan Hart83ce8c42014-06-02 00:07:06 -0700176 // cause the Topology replicas to diverge.
Jonathan Hart03102132014-07-01 23:22:04 -0700177 private class HostCleaner implements Runnable {
Ray Milkey269ffb92014-04-03 14:43:30 -0700178 @Override
179 public void run() {
Jonathan Hart03102132014-07-01 23:22:04 -0700180 log.debug("called HostCleaner");
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -0700181 mutableTopology.acquireReadLock();
Ray Milkey269ffb92014-04-03 14:43:30 -0700182 try {
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700183 Set<net.onrc.onos.core.topology.Host> deleteSet = new HashSet<>();
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -0700184 for (net.onrc.onos.core.topology.Host host : mutableTopology.getHosts()) {
TeruU5d2c9392014-06-09 20:02:02 -0700185 long now = System.currentTimeMillis();
Jonathan Hart03102132014-07-01 23:22:04 -0700186 if ((now - host.getLastSeenTime() > agingMillisecConfig)) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700187 if (log.isTraceEnabled()) {
Jonathan Hart03102132014-07-01 23:22:04 -0700188 log.trace("Removing host info: mac {}, now {}, lastSeenTime {}, diff {}",
189 host.getMacAddress(), now, host.getLastSeenTime(), now - host.getLastSeenTime());
Ray Milkey269ffb92014-04-03 14:43:30 -0700190 }
Jonathan Hart03102132014-07-01 23:22:04 -0700191 deleteSet.add(host);
Ray Milkey269ffb92014-04-03 14:43:30 -0700192 }
193 }
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -0700194
Yuta HIGUCHIbfc77f02014-07-14 22:50:25 -0700195 for (net.onrc.onos.core.topology.Host host : deleteSet) {
Jonathan Hart03102132014-07-01 23:22:04 -0700196 deleteHostByMac(host.getMacAddress());
Ray Milkey269ffb92014-04-03 14:43:30 -0700197 }
198 } catch (Exception e) {
Jonathan Hart83ce8c42014-06-02 00:07:06 -0700199 // Any exception thrown by the task will prevent the Executor
200 // from running the next iteration, so we need to catch and log
201 // all exceptions here.
Jonathan Hart03102132014-07-01 23:22:04 -0700202 log.error("Exception in host cleanup thread:", e);
TeruU5d2c9392014-06-09 20:02:02 -0700203 } finally {
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -0700204 mutableTopology.releaseReadLock();
Ray Milkey269ffb92014-04-03 14:43:30 -0700205 }
206 }
207 }
TeruU80ce5062014-03-03 17:16:13 -0800208
Jonathan Hartd857ad62013-12-14 18:08:17 -0800209 /**
Jonathan Hart03102132014-07-01 23:22:04 -0700210 * Parse a host from an {@link Ethernet} packet.
Ray Milkey269ffb92014-04-03 14:43:30 -0700211 *
Jonathan Hartd857ad62013-12-14 18:08:17 -0800212 * @param eth the packet to parse
Jonathan Hart83ce8c42014-06-02 00:07:06 -0700213 * @param swdpid the switch on which the packet arrived
214 * @param port the port on which the packet arrived
Jonathan Hart03102132014-07-01 23:22:04 -0700215 * @return the host from the packet
Jonathan Hartd857ad62013-12-14 18:08:17 -0800216 */
Jonathan Hart03102132014-07-01 23:22:04 -0700217 protected Host getSourceHostFromPacket(Ethernet eth,
218 long swdpid, long port) {
Jonathan Hart7ab71612014-05-27 13:37:31 -0700219 MACAddress sourceMac = eth.getSourceMAC();
Sangho Shin2f263692014-09-15 14:09:41 -0700220 int sourceIp = 0;
221
222
223 if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
224 IPv4 ipv4 = (IPv4)eth.getPayload();
225 sourceIp = ipv4.getSourceAddress();
226 }
227 else if (eth.getEtherType() == Ethernet.TYPE_ARP) {
228 ARP arp = (ARP)eth.getPayload();
229 sourceIp = IPv4Address.of(arp.getSenderProtocolAddress()).getInt();
230 }
Jonathan Hartd857ad62013-12-14 18:08:17 -0800231
Jonathan Hart7ab71612014-05-27 13:37:31 -0700232 // Ignore broadcast/multicast source
Sangho Shin2f263692014-09-15 14:09:41 -0700233 if (sourceMac.isBroadcast() || sourceMac.isMulticast()) {
Jonathan Hartd857ad62013-12-14 18:08:17 -0800234 return null;
Ray Milkeyb29e6262014-04-09 16:02:14 -0700235 }
Jonathan Hartd857ad62013-12-14 18:08:17 -0800236
237 short vlan = eth.getVlanID();
Jonathan Hart03102132014-07-01 23:22:04 -0700238 return new Host(sourceMac,
Sangho Shin2f263692014-09-15 14:09:41 -0700239 sourceIp,
Ray Milkey269ffb92014-04-03 14:43:30 -0700240 ((vlan >= 0) ? vlan : null),
Ray Milkey269ffb92014-04-03 14:43:30 -0700241 swdpid,
242 port,
243 new Date());
Jonathan Hartd857ad62013-12-14 18:08:17 -0800244 }
245
Ray Milkey269ffb92014-04-03 14:43:30 -0700246 @Override
247 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
248 List<Class<? extends IFloodlightService>> services =
249 new ArrayList<Class<? extends IFloodlightService>>();
Jonathan Hart03102132014-07-01 23:22:04 -0700250 services.add(IHostService.class);
Ray Milkey269ffb92014-04-03 14:43:30 -0700251 return services;
252 }
Jonathan Hartd857ad62013-12-14 18:08:17 -0800253
TeruUd1c5b652014-03-24 13:58:46 -0700254 @Override
Ray Milkey269ffb92014-04-03 14:43:30 -0700255 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
256 Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
257 new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
Jonathan Hart03102132014-07-01 23:22:04 -0700258 impls.put(IHostService.class, this);
Ray Milkey269ffb92014-04-03 14:43:30 -0700259 return impls;
260 }
261
TeruUd1c5b652014-03-24 13:58:46 -0700262 @Override
Ray Milkey269ffb92014-04-03 14:43:30 -0700263 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
264 List<Class<? extends IFloodlightService>> dependencies =
265 new ArrayList<Class<? extends IFloodlightService>>();
266 dependencies.add(IFloodlightProviderService.class);
Jonathan Harte37e4e22014-05-13 19:12:02 -0700267 dependencies.add(ITopologyService.class);
Ray Milkey269ffb92014-04-03 14:43:30 -0700268 return dependencies;
269 }
Yuta HIGUCHIe7eac182014-03-19 19:18:30 -0700270
Ray Milkey269ffb92014-04-03 14:43:30 -0700271 @Override
272 public void init(FloodlightModuleContext context)
273 throws FloodlightModuleException {
274 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
Jonathan Hart03102132014-07-01 23:22:04 -0700275 hostListeners = new CopyOnWriteArrayList<IHostListener>();
Jonathan Harte37e4e22014-05-13 19:12:02 -0700276 topologyService = context.getServiceImpl(ITopologyService.class);
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -0700277 mutableTopology = topologyService.getTopology();
TeruU28adcc32014-04-15 17:57:35 -0700278
Jonathan Hart03102132014-07-01 23:22:04 -0700279 setHostManagerProperties(context);
Ray Milkey269ffb92014-04-03 14:43:30 -0700280 }
TeruU80ce5062014-03-03 17:16:13 -0800281
Ray Milkey269ffb92014-04-03 14:43:30 -0700282 @Override
283 public void startUp(FloodlightModuleContext context) {
284 floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
Jonathan Hart03102132014-07-01 23:22:04 -0700285 EXECUTOR_SERVICE.scheduleAtFixedRate(new HostCleaner(),
286 HOST_CLEANING_INITIAL_DELAY, cleanupSecondConfig, TimeUnit.SECONDS);
Ray Milkey269ffb92014-04-03 14:43:30 -0700287 }
TeruUd1c5b652014-03-24 13:58:46 -0700288
Ray Milkey269ffb92014-04-03 14:43:30 -0700289 @Override
Jonathan Hart03102132014-07-01 23:22:04 -0700290 public void deleteHost(Host host) {
Jonathan Hart83ce8c42014-06-02 00:07:06 -0700291 floodlightProvider.publishUpdate(
Jonathan Hart03102132014-07-01 23:22:04 -0700292 new HostUpdate(host, HostUpdateType.DELETE));
Ray Milkey269ffb92014-04-03 14:43:30 -0700293 }
TeruUd1c5b652014-03-24 13:58:46 -0700294
Ray Milkey269ffb92014-04-03 14:43:30 -0700295 @Override
Jonathan Hart03102132014-07-01 23:22:04 -0700296 public void deleteHostByMac(MACAddress mac) {
297 Host deleteHost = null;
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -0700298 mutableTopology.acquireReadLock();
TeruU5d2c9392014-06-09 20:02:02 -0700299 try {
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -0700300 net.onrc.onos.core.topology.Host host = mutableTopology.getHostByMac(mac);
TeruU5d2c9392014-06-09 20:02:02 -0700301
Jonathan Hart03102132014-07-01 23:22:04 -0700302 for (Port switchPort : host.getAttachmentPoints()) {
TeruU5d2c9392014-06-09 20:02:02 -0700303 // We don't handle vlan now and multiple attachment points.
Jonathan Hart03102132014-07-01 23:22:04 -0700304 deleteHost = new Host(host.getMacAddress(),
Sangho Shin2f263692014-09-15 14:09:41 -0700305 host.getIpAddress(),
TeruU5d2c9392014-06-09 20:02:02 -0700306 null,
Yuta HIGUCHI8f3dfa32014-06-25 00:14:25 -0700307 switchPort.getDpid().value(),
Yuta HIGUCHI9da3a6e2014-06-10 22:11:58 -0700308 switchPort.getNumber().value(),
Jonathan Hart03102132014-07-01 23:22:04 -0700309 new Date(host.getLastSeenTime()));
Ray Milkey92897212014-07-21 10:33:16 -0700310 // FIXME: remove NOPMD flag after multiple attachment points are implemented
311 break; // NOPMD
TeruU5d2c9392014-06-09 20:02:02 -0700312 }
313 } finally {
Yuta HIGUCHId92b10c2014-08-25 09:30:28 -0700314 mutableTopology.releaseReadLock();
TeruU5d2c9392014-06-09 20:02:02 -0700315 }
316
Jonathan Hart03102132014-07-01 23:22:04 -0700317 if (deleteHost != null) {
318 deleteHost(deleteHost);
TeruU5d2c9392014-06-09 20:02:02 -0700319 }
Ray Milkey269ffb92014-04-03 14:43:30 -0700320 }
321
322 @Override
Jonathan Hart03102132014-07-01 23:22:04 -0700323 public void addHost(Long mac, Host host) {
Jonathan Hart83ce8c42014-06-02 00:07:06 -0700324 floodlightProvider.publishUpdate(
Jonathan Hart03102132014-07-01 23:22:04 -0700325 new HostUpdate(host, HostUpdateType.ADD));
Ray Milkey269ffb92014-04-03 14:43:30 -0700326 }
327
328 @Override
Jonathan Hart03102132014-07-01 23:22:04 -0700329 public void addHostListener(IHostListener listener) {
330 hostListeners.add(listener);
Ray Milkey269ffb92014-04-03 14:43:30 -0700331 }
332
333 @Override
Jonathan Hart03102132014-07-01 23:22:04 -0700334 public void removeHostListener(IHostListener listener) {
335 hostListeners.remove(listener);
Ray Milkey269ffb92014-04-03 14:43:30 -0700336 }
TeruU28adcc32014-04-15 17:57:35 -0700337
Jonathan Hart03102132014-07-01 23:22:04 -0700338 private void setHostManagerProperties(FloodlightModuleContext context) {
TeruU28adcc32014-04-15 17:57:35 -0700339 Map<String, String> configOptions = context.getConfigParams(this);
340 String cleanupsec = configOptions.get("cleanupsec");
341 String agingmsec = configOptions.get("agingmsec");
342 if (cleanupsec != null) {
343 cleanupSecondConfig = Integer.parseInt(cleanupsec);
344 log.debug("CLEANUP_SECOND is set to {}", cleanupSecondConfig);
345 }
346
347 if (agingmsec != null) {
348 agingMillisecConfig = Integer.parseInt(agingmsec);
349 log.debug("AGEING_MILLSEC is set to {}", agingMillisecConfig);
350 }
351 }
Jonathan Hartd857ad62013-12-14 18:08:17 -0800352}