[ONOS-5911] Port removal after receiving OFPR_DELETE port status reason.
Change-Id: I1f3f6c752da5f989a2d727f378e9f04fbbb71341
diff --git a/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java b/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java
index 89cc6e8..cc28227 100644
--- a/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java
@@ -34,6 +34,7 @@
private final PortNumber number;
private final boolean isEnabled;
+ private final boolean isRemoved;
private final Type type;
private final long portSpeed;
@@ -61,9 +62,26 @@
public DefaultPortDescription(PortNumber number, boolean isEnabled,
Type type, long portSpeed,
SparseAnnotations...annotations) {
+ this(number, isEnabled, false, type, portSpeed, annotations);
+ }
+
+ /**
+ * Creates a port description using the supplied information.
+ *
+ * @param number port number
+ * @param isEnabled port enabled state
+ * @param isRemoved port removed state
+ * @param type port type
+ * @param portSpeed port speed in Mbps
+ * @param annotations optional key/value annotations map
+ */
+ public DefaultPortDescription(PortNumber number, boolean isEnabled, boolean isRemoved,
+ Type type, long portSpeed,
+ SparseAnnotations...annotations) {
super(annotations);
this.number = checkNotNull(number);
this.isEnabled = isEnabled;
+ this.isRemoved = isRemoved;
this.type = type;
this.portSpeed = portSpeed;
}
@@ -72,6 +90,7 @@
protected DefaultPortDescription() {
this.number = null;
this.isEnabled = false;
+ this.isRemoved = false;
this.portSpeed = DEFAULT_SPEED;
this.type = Type.COPPER;
}
@@ -112,6 +131,11 @@
}
@Override
+ public boolean isRemoved() {
+ return isRemoved;
+ }
+
+ @Override
public Type type() {
return type;
}
diff --git a/core/api/src/main/java/org/onosproject/net/device/DeviceProviderService.java b/core/api/src/main/java/org/onosproject/net/device/DeviceProviderService.java
index f8c9442..ff34bd2 100644
--- a/core/api/src/main/java/org/onosproject/net/device/DeviceProviderService.java
+++ b/core/api/src/main/java/org/onosproject/net/device/DeviceProviderService.java
@@ -55,6 +55,17 @@
void updatePorts(DeviceId deviceId, List<PortDescription> portDescriptions);
/**
+ * Delete information about a single port of a device.
+ * It is up to the core to determine what has changed.
+ *
+ * @param deviceId identity of the device
+ * @param portDescription device port description
+ */
+ default void deletePort(DeviceId deviceId, PortDescription portDescription) {
+
+ }
+
+ /**
* Notifies the core about port status change of a single port.
*
* @param deviceId identity of the device
diff --git a/core/api/src/main/java/org/onosproject/net/device/PortDescription.java b/core/api/src/main/java/org/onosproject/net/device/PortDescription.java
index 31680e5..020794b 100644
--- a/core/api/src/main/java/org/onosproject/net/device/PortDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/device/PortDescription.java
@@ -40,6 +40,13 @@
boolean isEnabled();
/**
+ * Indicates whether or not the port was removed.
+ *
+ * @return true if the port is removed.
+ */
+ boolean isRemoved();
+
+ /**
* Returns the port type.
*
* @return port type
diff --git a/core/api/src/test/java/org/onosproject/net/device/DeviceProviderServiceAdapter.java b/core/api/src/test/java/org/onosproject/net/device/DeviceProviderServiceAdapter.java
index d6660d8..b471298 100644
--- a/core/api/src/test/java/org/onosproject/net/device/DeviceProviderServiceAdapter.java
+++ b/core/api/src/test/java/org/onosproject/net/device/DeviceProviderServiceAdapter.java
@@ -42,6 +42,11 @@
}
@Override
+ public void deletePort(DeviceId deviceId, PortDescription portDescription) {
+
+ }
+
+ @Override
public void portStatusChanged(DeviceId deviceId, PortDescription portDescription) {
}
diff --git a/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java b/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
index 6fbb21c..3b50882 100644
--- a/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
+++ b/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
@@ -592,6 +592,41 @@
}
@Override
+ public void deletePort(DeviceId deviceId, PortDescription basePortDescription) {
+
+ checkNotNull(deviceId, DEVICE_ID_NULL);
+ checkNotNull(basePortDescription, PORT_DESCRIPTION_NULL);
+ checkValidity();
+
+ if (!mastershipService.isLocalMaster(deviceId)) {
+ // Never been a master for this device
+ // any update will be ignored.
+ log.trace("Ignoring {} port update on standby node. {}", deviceId,
+ basePortDescription);
+ return;
+ }
+
+ Device device = getDevice(deviceId);
+ if (device == null) {
+ log.trace("Device not found: {}", deviceId);
+ }
+
+ PortDescription newPortDescription = new DefaultPortDescription(basePortDescription.portNumber(),
+ basePortDescription.isEnabled(),
+ true,
+ basePortDescription.type(),
+ basePortDescription.portSpeed(),
+ basePortDescription.annotations());
+ final DeviceEvent event = store.updatePortStatus(this.provider().id(),
+ deviceId,
+ newPortDescription);
+ if (event != null) {
+ log.info("Device {} port {} status changed", deviceId, event.port().number());
+ post(event);
+ }
+ }
+
+ @Override
public void receivedRoleReply(DeviceId deviceId, MastershipRole requested,
MastershipRole response) {
// Several things can happen here:
diff --git a/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java b/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java
index 4e6c05d..95db702 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java
@@ -736,6 +736,7 @@
private DeviceEvent updatePort(Device device, Port oldPort,
Port newPort,
Map<PortNumber, Port> ports) {
+
if (oldPort.isEnabled() != newPort.isEnabled() ||
oldPort.type() != newPort.type() ||
oldPort.portSpeed() != newPort.portSpeed() ||
@@ -746,6 +747,14 @@
return null;
}
+ private DeviceEvent removePort(DeviceId deviceId, PortNumber portNumber) {
+
+ log.info("Deleted port: " + deviceId.toString() + "/" + portNumber.toString());
+ Port deletedPort = devicePorts.get(deviceId).remove(portNumber);
+
+ return new DeviceEvent(PORT_REMOVED, getDevice(deviceId), deletedPort);
+ }
+
// Prunes the specified list of ports based on which ports are in the
// processed list and returns list of corresponding events.
// Guarded by deviceDescs value (=Device lock)
@@ -857,14 +866,16 @@
final PortNumber number = deltaDesc.value().portNumber();
final Port oldPort = ports.get(number);
final Port newPort;
-
final Timestamped<PortDescription> existingPortDesc = descs.getPortDesc(number);
+ boolean toDelete = false;
+
if (existingPortDesc == null ||
deltaDesc.isNewer(existingPortDesc)) {
// on new port or valid update
// update description
descs.putPortDesc(deltaDesc);
newPort = composePort(device, number, descsMap);
+ toDelete = deltaDesc.value().isRemoved();
} else {
// same or outdated event, ignored.
log.trace("ignore same or outdated {} >= {}", existingPortDesc, deltaDesc);
@@ -874,7 +885,7 @@
if (oldPort == null) {
return createPort(device, newPort, ports);
} else {
- return updatePort(device, oldPort, newPort, ports);
+ return toDelete ? removePort(deviceId, number) : updatePort(device, oldPort, newPort, ports);
}
}
}
diff --git a/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/DeviceProviderServiceClientProxy.java b/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/DeviceProviderServiceClientProxy.java
index c93a42a..bd133ad 100644
--- a/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/DeviceProviderServiceClientProxy.java
+++ b/incubator/rpc-grpc/src/main/java/org/onosproject/incubator/rpc/grpc/DeviceProviderServiceClientProxy.java
@@ -129,6 +129,11 @@
}
@Override
+ public void deletePort(DeviceId deviceId, PortDescription portDescription) {
+
+ }
+
+ @Override
public void portStatusChanged(DeviceId deviceId,
PortDescription portDescription) {
checkValidity();
diff --git a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
index 6119a1f..0acd186 100644
--- a/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
+++ b/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
@@ -450,7 +450,11 @@
public void portChanged(Dpid dpid, OFPortStatus status) {
LOG.debug("portChanged({},{})", dpid, status);
PortDescription portDescription = buildPortDescription(status);
- providerService.portStatusChanged(deviceId(uri(dpid)), portDescription);
+ if (status.getReason() != OFPortReason.DELETE) {
+ providerService.portStatusChanged(deviceId(uri(dpid)), portDescription);
+ } else {
+ providerService.deletePort(deviceId(uri(dpid)), portDescription);
+ }
}
@Override
@@ -819,7 +823,7 @@
PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
Port.Type type = port.getCurr().contains(OFPortFeatures.PF_FIBER) ? FIBER : COPPER;
SparseAnnotations annotations = makePortAnnotation(port.getName(), port.getHwAddr().toString());
- return new DefaultPortDescription(portNo, false, type,
+ return new DefaultPortDescription(portNo, false, true, type,
portSpeed(port), annotations);
}
}