Cherry-pick from https://gerrit.onos.onlab.us/#/c/338/
Lower the frequency of bug that PacketIn doesn't occur. (ONOS-1002)
Fixed a bug ProxyArpManager frequently deletes device from DB.
Change-Id: Ida1f8e36dee201b8d8dbd40325a2ee4a5c8736be
Fix compilation failure.
Change-Id: I0c3e253c6caa6f6b5315b30f2a647bb45d9c6b36
diff --git a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
index 9947eb0..3778632 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/forwarding/Forwarding.java
@@ -244,7 +244,7 @@
}
datagrid.sendPacketOutNotification(new BroadcastPacketOutNotification(
- eth.serialize(), sw.getId(), pi.getInPort()));
+ eth.serialize(), null, sw.getId(), pi.getInPort()));
}
private void handlePacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth){
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java
index 73d2163..135c061 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BroadcastPacketOutNotification.java
@@ -1,5 +1,8 @@
package net.onrc.onos.ofcontroller.proxyarp;
+import java.net.InetAddress;
+
+//TODO This class is too generic to be handled by ProxyArpService.
/**
* Notification to all ONOS instances to broadcast this packet out the edge of
* the network. The edge is defined as any port that doesn't have a link to
@@ -12,13 +15,15 @@
private static final long serialVersionUID = 1L;
+ private final InetAddress address;
private final long inSwitch;
private final short inPort;
- public BroadcastPacketOutNotification(byte[] packet, long inSwitch,
- short inPort) {
+ public BroadcastPacketOutNotification(byte[] packet, InetAddress address,
+ long inSwitch, short inPort) {
super(packet);
+ this.address = address;
this.inSwitch = inSwitch;
this.inPort = inPort;
}
@@ -31,4 +36,7 @@
return inPort;
}
+ public InetAddress getTargetAddress() {
+ return address;
+ }
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
index c7d495c..fd21265 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -87,22 +87,21 @@
private static class ArpRequest {
private final IArpRequester requester;
private final boolean retry;
+ private boolean sent = false;
private long requestTime;
public ArpRequest(IArpRequester requester, boolean retry){
this.requester = requester;
this.retry = retry;
- this.requestTime = System.currentTimeMillis();
}
public ArpRequest(ArpRequest old) {
this.requester = old.requester;
this.retry = old.retry;
- this.requestTime = System.currentTimeMillis();
}
public boolean isExpired() {
- return (System.currentTimeMillis() - requestTime) > ARP_REQUEST_TIMEOUT;
+ return sent && ((System.currentTimeMillis() - requestTime) > ARP_REQUEST_TIMEOUT);
}
public boolean shouldRetry() {
@@ -112,6 +111,11 @@
public void dispatchReply(InetAddress ipAddress, MACAddress replyMacAddress) {
requester.arpResponse(ipAddress, replyMacAddress);
}
+
+ public void setRequestTime() {
+ this.requestTime = System.currentTimeMillis();
+ this.sent = true;
+ }
}
private class HostArpRequester implements IArpRequester {
@@ -355,8 +359,8 @@
// We don't know the device so broadcast the request out
datagrid.sendPacketOutNotification(
- new BroadcastPacketOutNotification(eth.serialize(),
- sw.getId(), pi.getInPort()));
+ new BroadcastPacketOutNotification(eth.serialize(),
+ target, sw.getId(), pi.getInPort()));
}
else {
// Even if the device exists in our database, we do not reply to
@@ -383,7 +387,7 @@
datagrid.sendPacketOutNotification(
new BroadcastPacketOutNotification(eth.serialize(),
- sw.getId(), pi.getInPort()));
+ target, sw.getId(), pi.getInPort()));
}
else {
for (IPortObject portObject : outPorts) {
@@ -410,7 +414,7 @@
datagrid.sendPacketOutNotification(
new SinglePacketOutNotification(eth.serialize(),
- outSwitch, outPort));
+ target, outSwitch, outPort));
}
}
}
@@ -504,7 +508,8 @@
}
//sendArpRequestToSwitches(ipAddress, eth.serialize());
- datagrid.sendPacketOutNotification(new SinglePacketOutNotification(eth.serialize(),intf.getDpid(),intf.getPort()));
+ datagrid.sendPacketOutNotification(new SinglePacketOutNotification(eth.serialize(),
+ ipAddress, intf.getDpid(),intf.getPort()));
}
private void sendArpRequestToSwitches(InetAddress dstAddress, byte[] arpRequest) {
@@ -854,12 +859,28 @@
(SinglePacketOutNotification) packetOutNotification;
sendArpRequestOutPort(notification.packet, notification.getOutSwitch(),
notification.getOutPort());
+
+ // set timestamp
+ InetAddress addr = notification.getTargetAddress();
+ if (addr != null) {
+ for (ArpRequest request : arpRequests.get(addr)) {
+ request.setRequestTime();
+ }
+ }
}
else if (packetOutNotification instanceof BroadcastPacketOutNotification) {
BroadcastPacketOutNotification notification =
(BroadcastPacketOutNotification) packetOutNotification;
broadcastArpRequestOutMyEdge(notification.packet,
notification.getInSwitch(), notification.getInPort());
+
+ // set timestamp
+ InetAddress addr = notification.getTargetAddress();
+ if (addr != null) {
+ for (ArpRequest request : arpRequests.get(addr)) {
+ request.setRequestTime();
+ }
+ }
}
else {
log.warn("Unknown packet out notification received");
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java
index 1919d87..d654f67 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/SinglePacketOutNotification.java
@@ -1,5 +1,8 @@
package net.onrc.onos.ofcontroller.proxyarp;
+import java.net.InetAddress;
+
+// TODO This class is too generic to be handled by ProxyArpService.
/**
* Notification to another ONOS instance to send a packet out a single port.
*
@@ -8,13 +11,15 @@
private static final long serialVersionUID = 1L;
+ private final InetAddress address;
private final long outSwitch;
private final short outPort;
- public SinglePacketOutNotification(byte[] packet, long outSwitch,
- short outPort) {
+ public SinglePacketOutNotification(byte[] packet, InetAddress address,
+ long outSwitch, short outPort) {
super(packet);
+ this.address = address;
this.outSwitch = outSwitch;
this.outPort = outPort;
}
@@ -27,4 +32,7 @@
return outPort;
}
+ public InetAddress getTargetAddress() {
+ return address;
+ }
}