summary |
shortlog |
log |
commit | commitdiff |
review |
tree
raw |
patch |
inline | side by side (from parent 1:
8231526)
- Also added debug logs to trace how the ARP Handler is doing event syncs
Change-Id: I183c1eeb69e737eedd4d7b785cf974e8abd19b75
Signed-off-by: Giovanni Meo <gmeo@cisco.com>
public InetAddress getTargetIP() {
return tIP;
}
public InetAddress getTargetIP() {
return tIP;
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("ARPEvent [");
+ if (tIP != null) {
+ builder.append("tIP=")
+ .append(tIP);
+ }
+ builder.append("]");
+ return builder.toString();
+ }
import java.util.Arrays;
import org.opendaylight.controller.sal.core.NodeConnector;
import java.util.Arrays;
import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.utils.HexEncode;
/*
* ARP Reply event wrapper
*/
/*
* ARP Reply event wrapper
*/
public NodeConnector getPort() {
return port;
}
public NodeConnector getPort() {
return port;
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("ARPReply [");
+ if (port != null) {
+ builder.append("port=")
+ .append(port)
+ .append(", ");
+ }
+ if (tMac != null) {
+ builder.append("tMac=")
+ .append(HexEncode.bytesToHexString(tMac))
+ .append(", ");
+ }
+ if (sMac != null) {
+ builder.append("sMac=")
+ .append(HexEncode.bytesToHexString(sMac))
+ .append(", ");
+ }
+ if (sIP != null) {
+ builder.append("sIP=")
+ .append(sIP);
+ }
+ builder.append("]");
+ return builder.toString();
+ }
public HostNodeConnector getHost() {
return host;
}
public HostNodeConnector getHost() {
return host;
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("ARPRequest [");
+ if (subnet != null) {
+ builder.append("subnet=")
+ .append(subnet)
+ .append(", ");
+ }
+ if (host != null) {
+ builder.append("host=")
+ .append(host);
+ }
+ builder.append("]");
+ return builder.toString();
+ }
private ConcurrentMap<InetAddress, Short> countDownTimers;
private Timer periodicTimer;
private BlockingQueue<ARPCacheEvent> ARPCacheEvents = new LinkedBlockingQueue<ARPCacheEvent>();
private ConcurrentMap<InetAddress, Short> countDownTimers;
private Timer periodicTimer;
private BlockingQueue<ARPCacheEvent> ARPCacheEvents = new LinkedBlockingQueue<ARPCacheEvent>();
- Thread cacheEventHandler;
+ private Thread cacheEventHandler;
+ private boolean stopping = false;
/*
* A cluster allocated cache. Used for synchronizing ARP request/reply
* events across all cluster controllers. To raise an event, we put() a specific
/*
* A cluster allocated cache. Used for synchronizing ARP request/reply
* events across all cluster controllers. To raise an event, we put() a specific
try {
requestor = new HostNodeConnector(sourceMAC, sourceIP, p, subnet.getVlan());
} catch (ConstructionException e) {
try {
requestor = new HostNodeConnector(sourceMAC, sourceIP, p, subnet.getVlan());
} catch (ConstructionException e) {
- log.debug("Received ARP packet with invalid MAC: {}", sourceMAC);
+ log.debug("Received ARP packet with invalid MAC: {}", HexEncode.bytesToHexString(sourceMAC));
&& (NetUtils.isBroadcastMACAddr(targetMAC) || Arrays.equals(targetMAC, getControllerMAC()))) {
if (connectionManager.isLocal(p.getNode())){
if (log.isTraceEnabled()){
&& (NetUtils.isBroadcastMACAddr(targetMAC) || Arrays.equals(targetMAC, getControllerMAC()))) {
if (connectionManager.isLocal(p.getNode())){
if (log.isTraceEnabled()){
- log.trace("Received local ARP req. for default gateway. Replying with controller MAC: {}", getControllerMAC());
+ log.trace("Received local ARP req. for default gateway. Replying with controller MAC: {}",
+ HexEncode.bytesToHexString(getControllerMAC()));
}
sendARPReply(p, getControllerMAC(), targetIP, pkt.getSenderHardwareAddress(), sourceIP);
} else {
}
sendARPReply(p, getControllerMAC(), targetIP, pkt.getSenderHardwareAddress(), sourceIP);
} else {
//Raise a bcast request event, all controllers need to send one
log.trace("Sending a bcast ARP request for {}", targetIP);
arpRequestReplyEvent.put(new ARPRequest(targetIP, subnet), false);
//Raise a bcast request event, all controllers need to send one
log.trace("Sending a bcast ARP request for {}", targetIP);
arpRequestReplyEvent.put(new ARPRequest(targetIP, subnet), false);
} else {
/*
* Target host known (across the cluster), send ARP REPLY make sure that targetMAC
} else {
/*
* Target host known (across the cluster), send ARP REPLY make sure that targetMAC
* the targetIP as the target Network Address
*/
protected void sendBcastARPRequest(InetAddress targetIP, Subnet subnet) {
* the targetIP as the target Network Address
*/
protected void sendBcastARPRequest(InetAddress targetIP, Subnet subnet) {
+ log.trace("sendBcatARPRequest targetIP:{} subnet:{}", targetIP, subnet);
Set<NodeConnector> nodeConnectors;
if (subnet.isFlatLayer2()) {
nodeConnectors = new HashSet<NodeConnector>();
Set<NodeConnector> nodeConnectors;
if (subnet.isFlatLayer2()) {
nodeConnectors = new HashSet<NodeConnector>();
}
for (NodeConnector p : nodeConnectors) {
}
for (NodeConnector p : nodeConnectors) {
//fiter out any non-local or internal ports
if (! connectionManager.isLocal(p.getNode()) || topologyManager.isInternal(p)) {
continue;
}
//fiter out any non-local or internal ports
if (! connectionManager.isLocal(p.getNode()) || topologyManager.isInternal(p)) {
continue;
}
+ log.trace("Sending toward nodeConnector:{}", p);
ARP arp = new ARP();
byte[] senderIP = subnet.getNetworkAddress().getAddress();
byte[] targetIPByte = targetIP.getAddress();
ARP arp = new ARP();
byte[] senderIP = subnet.getNetworkAddress().getAddress();
byte[] targetIPByte = targetIP.getAddress();
* The sender MAC is the controller's MAC
*/
protected void sendUcastARPRequest(HostNodeConnector host, Subnet subnet) {
* The sender MAC is the controller's MAC
*/
protected void sendUcastARPRequest(HostNodeConnector host, Subnet subnet) {
+ log.trace("sendUcastARPRequest host:{} subnet:{}", host, subnet);
NodeConnector outPort = host.getnodeConnector();
if (outPort == null) {
log.error("Failed sending UcastARP because cannot extract output port from Host: {}", host);
NodeConnector outPort = host.getnodeConnector();
if (outPort == null) {
log.error("Failed sending UcastARP because cannot extract output port from Host: {}", host);
this.dataPacketService.transmitDataPacket(destPkt);
}
this.dataPacketService.transmitDataPacket(destPkt);
}
public void find(InetAddress networkAddress) {
log.trace("Received find IP {}", networkAddress);
public void find(InetAddress networkAddress) {
log.trace("Received find IP {}", networkAddress);
/*
* Probe the host by sending a unicast ARP Request to the host
*/
/*
* Probe the host by sending a unicast ARP Request to the host
*/
public void probe(HostNodeConnector host) {
log.trace("Received probe host {}", host);
public void probe(HostNodeConnector host) {
log.trace("Received probe host {}", host);
+ cacheEventHandler.interrupt();
startPeriodicTimer();
cacheEventHandler.start();
startPeriodicTimer();
cacheEventHandler.start();
}
private void generateAndSendReply(InetAddress sourceIP, byte[] sourceMAC) {
}
private void generateAndSendReply(InetAddress sourceIP, byte[] sourceMAC) {
+ if (log.isTraceEnabled()) {
+ log.trace("generateAndSendReply called with params sourceIP:{} sourceMAC:{}", sourceIP,
+ HexEncode.bytesToHexString(sourceMAC));
+ }
Set<HostNodeConnector> hosts = arpRequestors.remove(sourceIP);
if ((hosts == null) || hosts.isEmpty()) {
Set<HostNodeConnector> hosts = arpRequestors.remove(sourceIP);
if ((hosts == null) || hosts.isEmpty()) {
+ log.trace("Bailing out no requestors Hosts");
return;
}
countDownTimers.remove(sourceIP);
for (HostNodeConnector host : hosts) {
return;
}
countDownTimers.remove(sourceIP);
for (HostNodeConnector host : hosts) {
- log.trace("Sending ARP Reply with src {}/{}, target {}/{}",
- new Object[] { sourceMAC, sourceIP, host.getDataLayerAddressBytes(), host.getNetworkAddress() });
-
+ if (log.isTraceEnabled()) {
+ log.trace("Sending ARP Reply with src {}/{}, target {}/{}",
+ new Object[] {
+ HexEncode.bytesToHexString(sourceMAC),
+ sourceIP,
+ HexEncode.bytesToHexString(host.getDataLayerAddressBytes()),
+ host.getNetworkAddress() });
+ }
if (connectionManager.isLocal(host.getnodeconnectorNode())){
sendARPReply(host.getnodeConnector(),
sourceMAC,
if (connectionManager.isLocal(host.getnodeconnectorNode())){
sendARPReply(host.getnodeConnector(),
sourceMAC,
host.getDataLayerAddressBytes(),
host.getNetworkAddress());
} else {
host.getDataLayerAddressBytes(),
host.getNetworkAddress());
} else {
+ /*
+ * In the remote event a requestor moved to another
+ * controller it may turn out it now we need to send
+ * the ARP reply from a different controller, this
+ * cover the case
+ */
arpRequestReplyEvent.put(
new ARPReply(
host.getnodeConnector(),
arpRequestReplyEvent.put(
new ARPReply(
host.getnodeConnector(),
@Override
public void entryUpdated(ARPEvent key, Boolean new_value, String cacheName, boolean originLocal) {
@Override
public void entryUpdated(ARPEvent key, Boolean new_value, String cacheName, boolean originLocal) {
+ log.trace("Got and entryUpdated for cacheName {} key {} isNew {}", cacheName, key, new_value);
enqueueARPCacheEvent(key, new_value);
}
enqueueARPCacheEvent(key, new_value);
}
ARPCacheEvent cacheEvent = new ARPCacheEvent(event, new_value);
if (!ARPCacheEvents.contains(cacheEvent)) {
this.ARPCacheEvents.add(cacheEvent);
ARPCacheEvent cacheEvent = new ARPCacheEvent(event, new_value);
if (!ARPCacheEvents.contains(cacheEvent)) {
this.ARPCacheEvents.add(cacheEvent);
+ log.trace("Enqueued {}", event);
}
} catch (Exception e) {
log.debug("enqueueARPCacheEvent caught Interrupt Exception for event {}", event);
}
} catch (Exception e) {
log.debug("enqueueARPCacheEvent caught Interrupt Exception for event {}", event);
private class ARPCacheEventHandler implements Runnable {
@Override
public void run() {
private class ARPCacheEventHandler implements Runnable {
@Override
public void run() {
try {
ARPCacheEvent ev = ARPCacheEvents.take();
ARPEvent event = ev.getEvent();
try {
ARPCacheEvent ev = ARPCacheEvents.take();
ARPEvent event = ev.getEvent();
ARPRequest req = (ARPRequest) event;
// If broadcast request
if (req.getHost() == null) {
ARPRequest req = (ARPRequest) event;
// If broadcast request
if (req.getHost() == null) {
+ log.trace("Trigger and ARP Broadcast Request upon receipt of {}", req);
sendBcastARPRequest(req.getTargetIP(), req.getSubnet());
//If unicast and local, send reply
} else if (connectionManager.isLocal(req.getHost().getnodeconnectorNode())) {
sendBcastARPRequest(req.getTargetIP(), req.getSubnet());
//If unicast and local, send reply
} else if (connectionManager.isLocal(req.getHost().getnodeconnectorNode())) {
+ log.trace("ARPCacheEventHandler - sendUcatARPRequest upon receipt of {}", req);
sendUcastARPRequest(req.getHost(), req.getSubnet());
}
} else if (event instanceof ARPReply) {
ARPReply rep = (ARPReply) event;
// New reply received by controller, notify all awaiting requestors across the cluster
if (ev.isNewReply()) {
sendUcastARPRequest(req.getHost(), req.getSubnet());
}
} else if (event instanceof ARPReply) {
ARPReply rep = (ARPReply) event;
// New reply received by controller, notify all awaiting requestors across the cluster
if (ev.isNewReply()) {
+ log.trace("Trigger a generateAndSendReply in response to {}", rep);
generateAndSendReply(rep.getTargetIP(), rep.getTargetMac());
generateAndSendReply(rep.getTargetIP(), rep.getTargetMac());
// Otherwise, a specific reply. If local, send out.
} else if (connectionManager.isLocal(rep.getPort().getNode())) {
// Otherwise, a specific reply. If local, send out.
} else if (connectionManager.isLocal(rep.getPort().getNode())) {
+ log.trace("ARPCacheEventHandler - sendUcatARPReply locally in response to {}", rep);
sendARPReply(rep.getPort(),
rep.getSourceMac(),
rep.getSourceIP(),
sendARPReply(rep.getPort(),
rep.getSourceMac(),
rep.getSourceIP(),