import org.opendaylight.controller.clustering.services.CacheExistException;
import org.opendaylight.controller.clustering.services.IClusterContainerServices;
import org.opendaylight.controller.clustering.services.IClusterServices;
-import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
-import org.opendaylight.controller.hosttracker.hostAware.IHostFinder;
import org.opendaylight.controller.hosttracker.IfHostListener;
import org.opendaylight.controller.hosttracker.IfIptoHost;
import org.opendaylight.controller.hosttracker.IfNewHostNotify;
+import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
+import org.opendaylight.controller.hosttracker.hostAware.IHostFinder;
import org.opendaylight.controller.sal.core.ConstructionException;
import org.opendaylight.controller.sal.core.Edge;
import org.opendaylight.controller.sal.core.Host;
import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
import org.opendaylight.controller.sal.utils.GlobalConstants;
import org.opendaylight.controller.sal.utils.HexEncode;
+import org.opendaylight.controller.sal.utils.NetUtils;
import org.opendaylight.controller.sal.utils.NodeCreator;
import org.opendaylight.controller.sal.utils.Status;
import org.opendaylight.controller.sal.utils.StatusCode;
* removed the database
*/
-public class HostTracker implements IfIptoHost, IfHostListener,
- ISwitchManagerAware, IInventoryListener, ITopologyManagerAware {
- private static final Logger logger = LoggerFactory
- .getLogger(HostTracker.class);
+public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAware, IInventoryListener,
+ ITopologyManagerAware {
+ private static final Logger logger = LoggerFactory.getLogger(HostTracker.class);
private IHostFinder hostFinder;
private ConcurrentMap<InetAddress, HostNodeConnector> hostsDB;
/*
* added here until both come up
*/
private ConcurrentMap<NodeConnector, HostNodeConnector> inactiveStaticHosts;
- private Set<IfNewHostNotify> newHostNotify = Collections
- .synchronizedSet(new HashSet<IfNewHostNotify>());
+ private final Set<IfNewHostNotify> newHostNotify = Collections.synchronizedSet(new HashSet<IfNewHostNotify>());
private ITopologyManager topologyManager;
private IClusterContainerServices clusterContainerService = null;
private ISwitchManager switchManager = null;
private Timer timer;
- private Timer arp_refresh_timer;
+ private Timer arpRefreshTimer;
private String containerName = null;
-
+ private ExecutorService executor;
private static class ARPPending {
protected InetAddress hostIP;
protected short sent_count;
// This list contains the hosts for which ARP requests are being sent
// periodically
- private List<ARPPending> ARPPendingList = new ArrayList<HostTracker.ARPPending>();
+ private final List<ARPPending> ARPPendingList = new ArrayList<HostTracker.ARPPending>();
/*
* This list below contains the hosts which were initially in ARPPendingList
* above, but ARP response didn't come from there hosts after multiple
*
* We can't recover from condition 3 above
*/
- private ArrayList<ARPPending> failedARPReqList = new ArrayList<HostTracker.ARPPending>();
+ private final ArrayList<ARPPending> failedARPReqList = new ArrayList<HostTracker.ARPPending>();
public HostTracker() {
}
timer = new Timer();
timer.schedule(new OutStandingARPHandler(), 4000, 4000);
-
+ executor = Executors.newFixedThreadPool(2);
/* ARP Refresh Timer to go off every 5 seconds to implement ARP aging */
- arp_refresh_timer = new Timer();
- arp_refresh_timer.schedule(new ARPRefreshHandler(), 5000, 5000);
+ arpRefreshTimer = new Timer();
+ arpRefreshTimer.schedule(new ARPRefreshHandler(), 5000, 5000);
logger.debug("startUp: Caches created, timers started");
}
inactiveStaticHosts = new ConcurrentHashMap<NodeConnector, HostNodeConnector>();
}
- @SuppressWarnings("deprecation")
- private void destroyCache() {
- if (this.clusterContainerService == null) {
- logger.error("un-initialized clusterMger, can't destroy cache");
- return;
- }
- logger.debug("Destroying Cache for HostTracker");
- this.clusterContainerService.destroyCache("hostTrackerAH");
- this.clusterContainerService.destroyCache("hostTrackerIH");
- nonClusterObjectCreate();
- }
public void shutDown() {
}
return hostsDB.get(networkAddress);
}
- private Entry<NodeConnector, HostNodeConnector> getHostFromInactiveDB(
- InetAddress networkAddress) {
- for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts
- .entrySet()) {
+ private Entry<NodeConnector, HostNodeConnector> getHostFromInactiveDB(InetAddress networkAddress) {
+ for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts.entrySet()) {
if (entry.getValue().equalsByIP(networkAddress)) {
- logger.debug(
- "getHostFromInactiveDB(): Inactive Host found for IP:{} ",
- networkAddress.getHostAddress());
+ logger.debug("getHostFromInactiveDB(): Inactive Host found for IP:{} ", networkAddress.getHostAddress());
return entry;
}
}
- logger.debug(
- "getHostFromInactiveDB() Inactive Host Not found for IP: {}",
- networkAddress.getHostAddress());
+ logger.debug("getHostFromInactiveDB() Inactive Host Not found for IP: {}", networkAddress.getHostAddress());
return null;
}
private void removeHostFromInactiveDB(InetAddress networkAddress) {
NodeConnector nodeConnector = null;
- for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts
- .entrySet()) {
+ for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts.entrySet()) {
if (entry.getValue().equalsByIP(networkAddress)) {
nodeConnector = entry.getKey();
break;
}
if (nodeConnector != null) {
inactiveStaticHosts.remove(nodeConnector);
- logger.debug("removeHostFromInactiveDB(): Host Removed for IP: {}",
- networkAddress.getHostAddress());
+ logger.debug("removeHostFromInactiveDB(): Host Removed for IP: {}", networkAddress.getHostAddress());
return;
}
- logger.debug("removeHostFromInactiveDB(): Host Not found for IP: {}",
- networkAddress.getHostAddress());
+ logger.debug("removeHostFromInactiveDB(): Host Not found for IP: {}", networkAddress.getHostAddress());
}
protected boolean hostMoved(HostNodeConnector host) {
return false;
}
+ @Override
public HostNodeConnector hostQuery(InetAddress networkAddress) {
return hostsDB.get(networkAddress);
}
+ @Override
public Future<HostNodeConnector> discoverHost(InetAddress networkAddress) {
- ExecutorService executor = Executors.newFixedThreadPool(1);
if (executor == null) {
logger.error("discoverHost: Null executor");
return null;
}
- Callable<HostNodeConnector> worker = new HostTrackerCallable(this,
- networkAddress);
+ Callable<HostNodeConnector> worker = new HostTrackerCallable(this, networkAddress);
Future<HostNodeConnector> submit = executor.submit(worker);
return submit;
}
+ @Override
public HostNodeConnector hostFind(InetAddress networkAddress) {
/*
* Sometimes at boot with containers configured in the startup we hit
HostNodeConnector host = hostQuery(networkAddress);
if (host != null) {
- logger.debug("hostFind(): Host found for IP: {}",
- networkAddress.getHostAddress());
+ logger.debug("hostFind(): Host found for IP: {}", networkAddress.getHostAddress());
return host;
}
- /* host is not found, initiate a discovery */
- hostFinder.find(networkAddress);
- /* Also add this host to ARPPending List for any potential retries */
+
+ /* Add this host to ARPPending List for any potential retries */
+
AddtoARPPendingList(networkAddress);
- logger.debug(
- "hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...",
+ logger.debug("hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...",
networkAddress.getHostAddress());
+
+ /* host is not found, initiate a discovery */
+
+ hostFinder.find(networkAddress);
return null;
}
+ @Override
public Set<HostNodeConnector> getAllHosts() {
Set<HostNodeConnector> allHosts = new HashSet<HostNodeConnector>();
for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
@Override
public Set<HostNodeConnector> getInactiveStaticHosts() {
Set<HostNodeConnector> list = new HashSet<HostNodeConnector>();
- for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts
- .entrySet()) {
+ for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts.entrySet()) {
list.add(entry.getValue());
}
logger.debug("getInactiveStaticHosts(): Found {} Hosts", list.size());
private void removePendingARPFromList(int index) {
if (index >= ARPPendingList.size()) {
- logger.warn(
- "removePendingARPFromList(): index greater than the List. Size:{}, Index:{}",
+ logger.warn("removePendingARPFromList(): index greater than the List. Size:{}, Index:{}",
ARPPendingList.size(), index);
return;
}
htCallable.wakeup();
}
- public void setCallableOnPendingARP(InetAddress networkAddr,
- HostTrackerCallable callable) {
+ public void setCallableOnPendingARP(InetAddress networkAddr, HostTrackerCallable callable) {
ARPPending arphost;
for (int i = 0; i < ARPPendingList.size(); i++) {
arphost = ARPPendingList.get(i);
* the request
*/
removePendingARPFromList(i);
- logger.debug("Host Removed from ARPPending List, IP: {}",
- networkAddr);
+ logger.debug("Host Removed from ARPPending List, IP: {}", networkAddr);
return;
}
}
* the request
*/
failedARPReqList.remove(i);
- logger.debug("Host Removed from FailedARPReqList List, IP: {}",
- networkAddr);
+ logger.debug("Host Removed from FailedARPReqList List, IP: {}", networkAddr);
return;
}
}
// Learn a new Host
private void learnNewHost(HostNodeConnector host) {
host.initArpSendCountDown();
- hostsDB.put(host.getNetworkAddress(), host);
- logger.debug("New Host Learned: MAC: {} IP: {}",
- HexEncode.bytesToHexString(host.getDataLayerAddressBytes()),
- host.getNetworkAddress().getHostAddress());
+ HostNodeConnector rHost = hostsDB.putIfAbsent(host.getNetworkAddress(), host);
+ if (rHost != null) {
+ // Another host is already learned for this IP address, replace it
+ replaceHost(host.getNetworkAddress(), rHost, host);
+ } else {
+ logger.debug("New Host Learned: MAC: {} IP: {}", HexEncode.bytesToHexString(host
+ .getDataLayerAddressBytes()), host.getNetworkAddress().getHostAddress());
+ }
+ }
+
+ private void replaceHost(InetAddress networkAddr, HostNodeConnector removedHost, HostNodeConnector newHost) {
+ newHost.initArpSendCountDown();
+ if (hostsDB.replace(networkAddr, removedHost, newHost)) {
+ logger.debug("Host move occurred: Old Host IP:{}, New Host IP: {}", removedHost.getNetworkAddress()
+ .getHostAddress(), newHost.getNetworkAddress().getHostAddress());
+ logger.debug("Old Host MAC: {}, New Host MAC: {}",
+ HexEncode.bytesToHexString(removedHost.getDataLayerAddressBytes()),
+ HexEncode.bytesToHexString(newHost.getDataLayerAddressBytes()));
+ // Display the Old and New HostNodeConnectors also
+ logger.debug("Old {}, New {}", removedHost, newHost);
+ } else {
+ /*
+ * Host replacement has failed, do the recovery
+ */
+ hostsDB.put(networkAddr, newHost);
+ logger.error("Host replacement failed. Overwrite the host. Repalced Host: {}, New Host: {}", removedHost,
+ newHost);
+ }
+ notifyHostLearnedOrRemoved(removedHost, false);
+ notifyHostLearnedOrRemoved(newHost, true);
+ if (!newHost.isStaticHost()) {
+ ProcPendingARPReqs(networkAddr);
+ }
}
// Remove known Host
private void removeKnownHost(InetAddress key) {
HostNodeConnector host = hostsDB.get(key);
if (host != null) {
- logger.debug("Removing Host: IP:{}", host.getNetworkAddress()
- .getHostAddress());
+ logger.debug("Removing Host: IP:{}", host.getNetworkAddress().getHostAddress());
hostsDB.remove(key);
} else {
- logger.error(
- "removeKnownHost(): Host for IP address {} not found in hostsDB",
- key.getHostAddress());
+ logger.error("removeKnownHost(): Host for IP address {} not found in hostsDB", key.getHostAddress());
}
}
private class NotifyHostThread extends Thread {
- private HostNodeConnector host;
+ private final HostNodeConnector host;
public NotifyHostThread(HostNodeConnector h) {
this.host = h;
}
+ @Override
public void run() {
+ HostNodeConnector removedHost = null;
+ InetAddress networkAddr = host.getNetworkAddress();
+
/* Check for Host Move case */
if (hostMoved(host)) {
/*
* Host has been moved from one location (switch,port, MAC, or
- * VLAN). Remove the existing host with its previous location
- * parameters, inform the applications, and add it as a new Host
+ * VLAN) to another. Replace the existing host and its previous
+ * location parameters with new information, and notify the
+ * applications listening to host move.
*/
- HostNodeConnector removedHost = hostsDB.get(host
- .getNetworkAddress());
- removeKnownHost(host.getNetworkAddress());
+ removedHost = hostsDB.get(networkAddr);
if (removedHost != null) {
- notifyHostLearnedOrRemoved(removedHost, false);
- logger.debug(
- "Host move occurred. Old Host:{}, New Host: {}",
- removedHost, host);
+ replaceHost(networkAddr, removedHost, host);
+ return;
} else {
- logger.error(
- "Host to be removed not found in hostsDB. Host {}",
- removedHost);
+ logger.error("Host to be removed not found in hostsDB. Host {}", removedHost);
}
}
- /* check if there is an outstanding request for this host */
- InetAddress networkAddr = host.getNetworkAddress();
+ if (removedHost == null) {
+ // It is a new host
+ learnNewHost(host);
+ }
- // add and notify
- learnNewHost(host);
+ /* check if there is an outstanding request for this host */
ProcPendingARPReqs(networkAddr);
notifyHostLearnedOrRemoved(host, true);
}
}
+ @Override
public void hostListener(HostNodeConnector host) {
+ logger.debug("ARP received for Host: IP {}, MAC {}, {}", host.getNetworkAddress().getHostAddress(),
+ HexEncode.bytesToHexString(host.getDataLayerAddressBytes()), host);
if (hostExists(host)) {
- logger.debug("ARP received for Host: {}", host);
- HostNodeConnector existinghost = hostsDB.get(host
- .getNetworkAddress());
+ HostNodeConnector existinghost = hostsDB.get(host.getNetworkAddress());
existinghost.initArpSendCountDown();
return;
}
private void notifyHostLearnedOrRemoved(HostNodeConnector host, boolean add) {
// Update listeners if any
if (newHostNotify != null) {
+ logger.debug("Notifying Applications for Host {} Being {}", host.getNetworkAddress().getHostAddress(),
+ add ? "Added" : "Deleted");
synchronized (this.newHostNotify) {
for (IfNewHostNotify ta : newHostNotify) {
try {
Host h = null;
NodeConnector p = host.getnodeConnector();
try {
- DataLinkAddress dla = new EthernetAddress(
- host.getDataLayerAddressBytes());
- h = new org.opendaylight.controller.sal.core.Host(dla,
- host.getNetworkAddress());
+ DataLinkAddress dla = new EthernetAddress(host.getDataLayerAddressBytes());
+ h = new Host(dla, host.getNetworkAddress());
} catch (ConstructionException ce) {
p = null;
h = null;
}
if (topologyManager != null && p != null && h != null) {
+ logger.debug("Notifying Topology Manager for Host {} Being {}", h.getNetworkAddress().getHostAddress(),
+ add ? "Added" : "Deleted");
if (add == true) {
Tier tier = new Tier(1);
switchManager.setNodeProp(node, tier);
private void updateSwitchTiers(Node n, int currentTier) {
Map<Node, Set<Edge>> ndlinks = topologyManager.getNodeEdges();
if (ndlinks == null) {
- logger.debug(
- "updateSwitchTiers(): ndlinks null for Node: {}, Tier:{}",
- n, currentTier);
+ logger.debug("updateSwitchTiers(): ndlinks null for Node: {}, Tier:{}", n, currentTier);
return;
}
Set<Edge> links = ndlinks.get(n);
if (links == null) {
- logger.debug("updateSwitchTiers(): links null for ndlinks:{}",
- ndlinks);
+ logger.debug("updateSwitchTiers(): links null for ndlinks:{}", ndlinks);
return;
}
ArrayList<Node> needsVisiting = new ArrayList<Node>();
for (Edge lt : links) {
- if (!lt.getHeadNodeConnector().getType()
- .equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) {
+ if (!lt.getHeadNodeConnector().getType().equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) {
// We don't want to work on Node that are not openflow
// for now
continue;
private boolean switchNeedsTieringUpdate(Node n, int tier) {
if (n == null) {
- logger.error("switchNeedsTieringUpdate(): Null node for tier: {}",
- tier);
+ logger.error("switchNeedsTieringUpdate(): Null node for tier: {}", tier);
return false;
}
/*
* @return Network Hierarchies represented by an Array of Array (of
* Switch-Ids as String).
*/
+ @Override
public List<List<String>> getHostNetworkHierarchy(InetAddress hostAddress) {
HostNodeConnector host = hostQuery(hostAddress);
if (host == null)
* Array of multiple Hierarchies that represent a given host.
*/
@SuppressWarnings("unchecked")
- private void updateCurrentHierarchy(Node node,
- ArrayList<String> currHierarchy, List<List<String>> fullHierarchy) {
+ private void updateCurrentHierarchy(Node node, ArrayList<String> currHierarchy, List<List<String>> fullHierarchy) {
// currHierarchy.add(String.format("%x", currSw.getId()));
currHierarchy.add(dpidToHostNameHack((Long) node.getID()));
- ArrayList<String> currHierarchyClone = (ArrayList<String>) currHierarchy
- .clone(); // Shallow copy as required
+ ArrayList<String> currHierarchyClone = (ArrayList<String>) currHierarchy.clone(); // Shallow
+ // copy
+ // as
+ // required
Map<Node, Set<Edge>> ndlinks = topologyManager.getNodeEdges();
if (ndlinks == null) {
- logger.debug(
- "updateCurrentHierarchy(): topologyManager returned null ndlinks for node: {}",
- node);
+ logger.debug("updateCurrentHierarchy(): topologyManager returned null ndlinks for node: {}", node);
return;
}
Node n = NodeCreator.createOFNode((Long) node.getID());
return;
}
for (Edge lt : links) {
- if (!lt.getHeadNodeConnector().getType()
- .equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) {
+ if (!lt.getHeadNodeConnector().getType().equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) {
// We don't want to work on Node that are not openflow
// for now
continue;
}
Node dstNode = lt.getHeadNodeConnector().getNode();
- Tier nodeTier = (Tier) switchManager.getNodeProp(node,
- Tier.TierPropName);
- Tier dstNodeTier = (Tier) switchManager.getNodeProp(dstNode,
- Tier.TierPropName);
+ Tier nodeTier = (Tier) switchManager.getNodeProp(node, Tier.TierPropName);
+ Tier dstNodeTier = (Tier) switchManager.getNodeProp(dstNode, Tier.TierPropName);
if (dstNodeTier.getValue() > nodeTier.getValue()) {
ArrayList<String> buildHierarchy = currHierarchy;
if (currHierarchy.size() > currHierarchyClone.size()) {
- buildHierarchy = (ArrayList<String>) currHierarchyClone
- .clone(); // Shallow copy as required
+ buildHierarchy = (ArrayList<String>) currHierarchyClone.clone(); // Shallow
+ // copy
+ // as
+ // required
fullHierarchy.add(buildHierarchy);
}
updateCurrentHierarchy(dstNode, buildHierarchy, fullHierarchy);
}
if (!srcType.equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) {
- logger.error("For now we cannot handle updates for "
- + "non-openflow nodes");
+ logger.error("For now we cannot handle updates for " + "non-openflow nodes");
return;
}
}
if (!dstType.equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) {
- logger.error("For now we cannot handle updates for "
- + "non-openflow nodes");
+ logger.error("For now we cannot handle updates for " + "non-openflow nodes");
return;
}
}
}
- logger.debug(
- "HostTracker Topology linkUpdate handling src:{}[port {}] dst:{}[port {}] added: {}",
+ logger.debug("HostTracker Topology linkUpdate handling src:{}[port {}] dst:{}[port {}] added: {}",
new Object[] { srcNid, srcPort, dstNid, dstPort, added });
}
}
}
+ @Override
public void subnetNotify(Subnet sub, boolean add) {
logger.debug("Received subnet notification: {} add={}", sub, add);
if (add) {
for (int i = 0; i < failedARPReqList.size(); i++) {
ARPPending arphost;
arphost = failedARPReqList.get(i);
- logger.debug(
- "Sending the ARP from FailedARPReqList fors IP: {}",
- arphost.getHostIP().getHostAddress());
- hostFinder.find(arphost.getHostIP());
+ if (hostFinder == null) {
+ logger.warn("ARPHandler Services are not available on subnet addition");
+ continue;
+ }
+ logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
+ hostFinder.find(arphost.getHostIP());
}
}
}
class OutStandingARPHandler extends TimerTask {
+ @Override
public void run() {
ARPPending arphost;
/* This routine runs every 4 seconds */
- // logger.info ("ARP Handler called");
for (int i = 0; i < ARPPendingList.size(); i++) {
arphost = ARPPendingList.get(i);
if (arphost.getSent_count() < switchManager.getHostRetryCount()) {
/*
* No reply has been received of first ARP Req, send the
- * next one
+ * next one. Before sending the ARP, check if ARPHandler
+ * is available or not
*/
+ if (hostFinder == null) {
+ logger.warn("ARPHandler Services are not available for Outstanding ARPs");
+ continue;
+ }
hostFinder.find(arphost.getHostIP());
arphost.sent_count++;
- logger.debug("ARP Sent from ARPPending List, IP: {}",
- arphost.getHostIP().getHostAddress());
- } else if (arphost.getSent_count() >= switchManager
- .getHostRetryCount()) {
+ logger.debug("ARP Sent from ARPPending List, IP: {}", arphost.getHostIP().getHostAddress());
+ } else if (arphost.getSent_count() >= switchManager.getHostRetryCount()) {
/*
- * Two ARP requests have been sent without receiving a
+ * ARP requests have been sent without receiving a
* reply, remove this from the pending list
*/
removePendingARPFromList(i);
- logger.debug(
- "ARP reply not received after two attempts, removing from Pending List IP: {}",
+ logger.debug("ARP reply not received after multiple attempts, removing from Pending List IP: {}",
arphost.getHostIP().getHostAddress());
/*
* Add this host to a different list which will be processed
* on link up events
*/
- logger.debug("Adding the host to FailedARPReqList IP: {}",
- arphost.getHostIP().getHostAddress());
+ logger.debug("Adding the host to FailedARPReqList IP: {}", arphost.getHostIP().getHostAddress());
failedARPReqList.add(arphost);
} else {
- logger.error(
- "Inavlid arp_sent count for entery at index: {}", i);
+ logger.error("Inavlid arp_sent count for entry at index: {}", i);
}
}
}
}
private class ARPRefreshHandler extends TimerTask {
+ @Override
@SuppressWarnings("deprecation")
public void run() {
- if ((clusterContainerService != null)
- && !clusterContainerService.amICoordinator()) {
+ if ((clusterContainerService != null) && !clusterContainerService.amICoordinator()) {
return;
}
- if ((switchManager != null)
- && !switchManager.isHostRefreshEnabled()) {
+ if ((switchManager != null) && !switchManager.isHostRefreshEnabled()) {
/*
* The host probe procedure was disabled by CLI
*/
logger.error("ARPRefreshHandler(): hostsDB is not allocated yet:");
return;
}
- for (Entry<InetAddress, HostNodeConnector> entry : hostsDB
- .entrySet()) {
+ for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
HostNodeConnector host = entry.getValue();
if (host.isStaticHost()) {
/* this host was learned via API3, don't age it out */
* there
*/
if (logger.isTraceEnabled()) {
- logger.trace(
- "ARP Probing ({}) for {}({})",
- new Object[] {
- arp_cntdown,
- host.getNetworkAddress().getHostAddress(),
- HexEncode.bytesToHexString(host
- .getDataLayerAddressBytes()) });
+ logger.trace(
+ "ARP Probing ({}) for {}({})",
+ new Object[] { arp_cntdown, host.getNetworkAddress().getHostAddress(),
+ HexEncode.bytesToHexString(host.getDataLayerAddressBytes()) });
}
host.setArpSendCountDown(arp_cntdown);
+ if (hostFinder == null) {
+ /*
+ * If hostfinder is not available, then can't send the
+ * probe. However, continue the age out the hosts since
+ * we don't know if the host is indeed out there or not.
+ */
+ logger.warn("ARPHandler is not avaialable, can't send the probe");
+ continue;
+ }
hostFinder.probe(host);
}
}
* indicating the result of this action.
*/
- public Status addStaticHostReq(InetAddress networkAddr,
- byte[] dataLayerAddress, NodeConnector nc, short vlan) {
- if (dataLayerAddress.length != 6) {
+ public Status addStaticHostReq(InetAddress networkAddr, byte[] dataLayerAddress, NodeConnector nc, short vlan) {
+ if (dataLayerAddress.length != NetUtils.MACAddrLengthInBytes) {
return new Status(StatusCode.BADREQUEST, "Invalid MAC address");
}
+ if (nc == null) {
+ return new Status(StatusCode.BADREQUEST, "Invalid NodeConnector");
+ }
HostNodeConnector host = null;
try {
- host = new HostNodeConnector(dataLayerAddress, networkAddr, nc,
- vlan);
+ host = new HostNodeConnector(dataLayerAddress, networkAddr, nc, vlan);
if (hostExists(host)) {
// This host is already learned either via ARP or through a
// northbound request
transHost.setStaticHost(true);
return new Status(StatusCode.SUCCESS, null);
}
+
+ if (hostsDB.get(networkAddr) != null) {
+ // There is already a host with this IP address (but behind
+ // a different (switch, port, vlan) tuple. Return an error
+ return new Status(StatusCode.CONFLICT, "Existing IP, Use PUT to update");
+ }
host.setStaticHost(true);
+ /*
+ * Check if the nc is an ISL port
+ */
+ if (topologyManager != null) {
+ if (topologyManager.isInternal(nc)) {
+ return new Status(StatusCode.BADREQUEST, "Cannot add host on ISL port");
+ }
+ }
/*
* Before adding host, Check if the switch and the port have already
* come up
notifyHostLearnedOrRemoved(host, true);
} else {
inactiveStaticHosts.put(nc, host);
- logger.debug(
- "Switch or switchport is not up, adding host {} to inactive list",
+ logger.debug("Switch or switchport is not up, adding host {} to inactive list",
networkAddr.getHostName());
}
return new Status(StatusCode.SUCCESS, null);
} catch (ConstructionException e) {
- return new Status(StatusCode.INTERNALERROR,
- "Host could not be created");
+ logger.error("", e);
+ return new Status(StatusCode.INTERNALERROR, "Host could not be created");
}
}
* @param vlan
* Vlan of which this host is member of
*
- * @return boolean true if the host was added successfully, false otherwise
+ * @return Status The status object as described in {@code Status}
+ * indicating the result of this action.
*/
- public boolean updateHostReq(InetAddress networkAddr,
- byte[] dataLayerAddress, NodeConnector nc, short vlan) {
+ public Status updateHostReq(InetAddress networkAddr, byte[] dataLayerAddress, NodeConnector nc, short vlan) {
+ HostNodeConnector tobeUpdatedHost;
+ HostNodeConnector host = null;
+
+ if (dataLayerAddress.length != NetUtils.MACAddrLengthInBytes) {
+ return new Status(StatusCode.BADREQUEST, "Invalid MAC address");
+ }
+
if (nc == null) {
- return false;
+ return new Status(StatusCode.BADREQUEST, "Invalid NodeConnector");
}
- HostNodeConnector host = null;
+
try {
- host = new HostNodeConnector(dataLayerAddress, networkAddr, nc,
- vlan);
- if (!hostExists(host)) {
- if ((inactiveStaticHosts.get(nc)) != null) {
- inactiveStaticHosts.replace(nc, host);
- return true;
+ host = new HostNodeConnector(dataLayerAddress, networkAddr, nc, vlan);
+ if (hostExists(host)) {
+ return new Status(StatusCode.BADREQUEST, "Host already exists");
+ }
+
+ if ((tobeUpdatedHost = hostsDB.get(networkAddr)) != null) {
+ if (hostsDB.replace(networkAddr, tobeUpdatedHost, host)) {
+ logger.debug("Host replaced from hostsDB. Old host: {} New Host: {}", tobeUpdatedHost, host);
+ notifyHostLearnedOrRemoved(tobeUpdatedHost, false);
+ notifyHostLearnedOrRemoved(host, true);
+ return new Status(StatusCode.SUCCESS);
+ } else {
+ logger.error("Static host replacement failed from hostsDB, Replaced Host: {}, New Host: {}",
+ tobeUpdatedHost, host);
+ return new Status(StatusCode.INTERNALERROR,
+ "Host Replacement Failed due to presence of another host with same IP");
}
- return false;
}
- hostsDB.replace(networkAddr, host);
- return true;
+
+ // Check if the host exists in inactive hosts database
+ if ((tobeUpdatedHost = inactiveStaticHosts.get(nc)) != null) {
+ if (inactiveStaticHosts.replace(nc, tobeUpdatedHost, host)) {
+ logger.debug("Host replaced from inactive hostsDB. Old host: {} New Host: {}", tobeUpdatedHost,
+ host);
+ return new Status(StatusCode.SUCCESS);
+ } else {
+ logger.error("Static host replacement failed, Replaced Host: {}, New Host: {}", tobeUpdatedHost,
+ host);
+ return new Status(StatusCode.INTERNALERROR,
+ "Host Replacement Failed due to presence of another host with same IP");
+ }
+ }
+
+ // Host doesn't exist
+ return new Status(StatusCode.BADREQUEST, "Host doesn't exists, can't update");
} catch (ConstructionException e) {
+ logger.error("", e);
+ return new Status(StatusCode.INTERNALERROR, "host object creation failure");
}
- return false;
}
/**
if (host != null) {
// Validation check
if (!host.isStaticHost()) {
- return new Status(StatusCode.FORBIDDEN, "Host "
- + networkAddress.getHostName() + " is not static");
+ return new Status(StatusCode.FORBIDDEN, "Host " + networkAddress.getHostName() + " is not static");
}
// Remove and notify
notifyHostLearnedOrRemoved(host, false);
host = entry.getValue();
// Validation check
if (!host.isStaticHost()) {
- return new Status(StatusCode.FORBIDDEN, "Host "
- + networkAddress.getHostName() + " is not static");
+ return new Status(StatusCode.FORBIDDEN, "Host " + networkAddress.getHostName() + " is not static");
}
this.removeHostFromInactiveDB(networkAddress);
return new Status(StatusCode.SUCCESS, null);
}
@Override
- public void notifyNode(Node node, UpdateType type,
- Map<String, Property> propMap) {
+ public void notifyNode(Node node, UpdateType type, Map<String, Property> propMap) {
if (node == null)
return;
switch (type) {
case REMOVED:
logger.debug("Received removed node {}", node);
- for (Entry<InetAddress, HostNodeConnector> entry : hostsDB
- .entrySet()) {
+ for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
HostNodeConnector host = entry.getValue();
if (host.getnodeconnectorNode().equals(node)) {
logger.debug("Node: {} is down, remove from Hosts_DB", node);
}
@Override
- public void notifyNodeConnector(NodeConnector nodeConnector,
- UpdateType type, Map<String, Property> propMap) {
+ public void notifyNodeConnector(NodeConnector nodeConnector, UpdateType type, Map<String, Property> propMap) {
if (nodeConnector == null)
return;
}
@Override
- public Status addStaticHost(String networkAddress, String dataLayerAddress,
- NodeConnector nc, String vlan) {
+ public Status addStaticHost(String networkAddress, String dataLayerAddress, NodeConnector nc, String vlan) {
try {
InetAddress ip = InetAddress.getByName(networkAddress);
if (nc == null) {
return new Status(StatusCode.BADREQUEST, "Invalid NodeId");
}
- return addStaticHostReq(ip,
- HexEncode.bytesFromHexString(dataLayerAddress), nc,
- Short.valueOf(vlan));
+ return addStaticHostReq(ip, HexEncode.bytesFromHexString(dataLayerAddress), nc, Short.valueOf(vlan));
} catch (UnknownHostException e) {
logger.error("", e);
return new Status(StatusCode.BADREQUEST, "Invalid Address");
for (int i = 0; i < failedARPReqList.size(); i++) {
arphost = failedARPReqList.get(i);
- logger.debug("Sending the ARP from FailedARPReqList fors IP: {}",
- arphost.getHostIP().getHostAddress());
+ logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
+ if (hostFinder == null) {
+ logger.warn("ARPHandler is not available at interface up");
+ logger.warn("Since this event is missed, host(s) connected to interface {} may not be discovered",
+ nodeConnector);
+ continue;
+ }
hostFinder.find(arphost.getHostIP());
}
HostNodeConnector host = inactiveStaticHosts.get(nodeConnector);
}
private void handleNodeConnectorStatusDown(NodeConnector nodeConnector) {
- long sid = (Long) nodeConnector.getNode().getID();
- short port = (Short) nodeConnector.getID();
-
logger.debug("handleNodeConnectorStatusDown {}", nodeConnector);
for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
HostNodeConnector host = entry.getValue();
- if ((host.getnodeconnectornodeId() == sid)
- && (host.getnodeconnectorportId() == port)) {
- logger.debug(
- "Switch: {}, Port: {} is down, remove from Hosts_DB",
- sid, port);
+ if (host.getnodeConnector().equals(nodeConnector)) {
+ logger.debug(" NodeConnector: {} is down, remove from Hosts_DB", nodeConnector);
removeKnownHost(entry.getKey());
notifyHostLearnedOrRemoved(host, false);
}
*
*/
void destroy() {
- destroyCache();
}
/**
* calls
*
*/
- void stop() {
+ void stop(){
+ }
+
+ void stopping() {
+ arpRefreshTimer.cancel();
+ timer.cancel();
+ executor.shutdown();
}
@Override