[ONOS-3697] Remove flow rules and dhcp mapping for router when it is removed.
Change-Id: I24e7c6d3fa0731822250c84ac5807f6192d371bf
diff --git a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/impl/OpenstackPortInfo.java b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/impl/OpenstackPortInfo.java
index 6207228..1b6250e 100644
--- a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/impl/OpenstackPortInfo.java
+++ b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/impl/OpenstackPortInfo.java
@@ -16,6 +16,7 @@
package org.onosproject.openstackswitching.impl;
import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
import org.onosproject.net.DeviceId;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -27,11 +28,13 @@
private final Ip4Address hostIp;
private final DeviceId deviceId;
+ private final MacAddress hostMac;
private final long vni;
- public OpenstackPortInfo(Ip4Address hostIp, DeviceId deviceId,
+ public OpenstackPortInfo(Ip4Address hostIp, MacAddress hostMac, DeviceId deviceId,
long vni) {
this.hostIp = hostIp;
+ this.hostMac = hostMac;
this.deviceId = deviceId;
this.vni = vni;
}
@@ -40,6 +43,10 @@
return hostIp;
}
+ public MacAddress mac() {
+ return hostMac;
+ }
+
public DeviceId deviceId() {
return deviceId;
}
@@ -54,6 +61,7 @@
public static final class Builder {
private Ip4Address hostIp;
+ private MacAddress hostMac;
private DeviceId deviceId;
private long vni;
@@ -62,6 +70,11 @@
return this;
}
+ public Builder setHostMac(MacAddress hostMac) {
+ this.hostMac = checkNotNull(hostMac, "hostMac cannot be bull");
+ return this;
+ }
+
public Builder setDeviceId(DeviceId deviceId) {
this.deviceId = checkNotNull(deviceId, "deviceId cannot be null");
return this;
@@ -78,6 +91,7 @@
private OpenstackPortInfo(Builder builder) {
hostIp = builder.hostIp;
+ hostMac = builder.hostMac;
deviceId = builder.deviceId;
vni = builder.vni;
}
diff --git a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/impl/OpenstackSwitchingManager.java b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/impl/OpenstackSwitchingManager.java
index a1b2f06..49dff3f 100644
--- a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/impl/OpenstackSwitchingManager.java
+++ b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/impl/OpenstackSwitchingManager.java
@@ -104,10 +104,12 @@
protected DriverService driverService;
public static final String PORTNAME_PREFIX_VM = "tap";
- public static final String PORTNAME_PREFIX_ROUTER = "qr";
+ public static final String PORTNAME_PREFIX_ROUTER = "qr-";
public static final String PORTNAME_PREFIX_TUNNEL = "vxlan";
public static final String PORTNAME = "portName";
+ public static final String DEVICE_OWNER_GATEWAY = "network:router_gateway";
+
private ApplicationId appId;
private boolean doNotPushFlows;
private Ip4Address neutronServer;
@@ -170,14 +172,38 @@
@Override
public void createPorts(OpenstackPort openstackPort) {
- if (!openstackPort.fixedIps().isEmpty()) {
+ if (!openstackPort.fixedIps().isEmpty()
+ && !openstackPort.deviceOwner().equals(DEVICE_OWNER_GATEWAY)) {
registerDhcpInfo(openstackPort);
}
}
@Override
public void deletePort(String uuid) {
+ // When VMs are remvoed, the flow rules for the VMs are removed using ONOS port update event.
+ // But, when router is removed, no ONOS port event occurs and we need to use Neutron port event.
+ // Here we should not touch any rules for VMs.
+ log.debug("port {} was removed", uuid);
+ String routerPortName = PORTNAME_PREFIX_ROUTER + uuid.substring(0, 11);
+ OpenstackPortInfo routerPortInfo = openstackPortInfoMap.get(routerPortName);
+ if (routerPortInfo != null) {
+ dhcpService.removeStaticMapping(routerPortInfo.mac());
+ if (!doNotPushFlows) {
+ deviceService.getPorts(routerPortInfo.deviceId()).forEach(port -> {
+ String pName = port.annotations().value("portName");
+ if (pName.equals(routerPortName)) {
+ OpenstackSwitchingRulePopulator rulePopulator =
+ new OpenstackSwitchingRulePopulator(appId, flowObjectiveService,
+ deviceService, restHandler, driverService);
+
+ rulePopulator.removeSwitchingRules(doNotPushFlows, port, openstackPortInfoMap);
+ openstackPortInfoMap.remove(routerPortName);
+ return;
+ }
+ });
+ }
+ }
}
@Override
@@ -268,17 +294,17 @@
OpenstackSwitchingRulePopulator rulePopulator =
new OpenstackSwitchingRulePopulator(appId, flowObjectiveService,
deviceService, restHandler, driverService);
- rulePopulator.populateSwitchingRules(device, port);
+ rulePopulator.populateSwitchingRules(doNotPushFlows, device, port);
updatePortMap(device.id(), port, restHandler.getNetworks(), rulePopulator.openstackPort(port));
-
//In case portupdate event is driven by vm shutoff from openstack
} else if (!port.isEnabled() && openstackPortInfoMap.containsKey(port.annotations().value(PORTNAME))) {
log.debug("Flowrules according to the port {} were removed", port.number().toString());
OpenstackSwitchingRulePopulator rulePopulator =
new OpenstackSwitchingRulePopulator(appId, flowObjectiveService,
deviceService, restHandler, driverService);
- openstackPortInfoMap.get(port.annotations().value(PORTNAME));
- rulePopulator.removeSwitchingRules(port, openstackPortInfoMap);
+
+ rulePopulator.removeSwitchingRules(doNotPushFlows, port, openstackPortInfoMap);
+ dhcpService.removeStaticMapping(openstackPortInfoMap.get(port.annotations().value(PORTNAME)).mac());
openstackPortInfoMap.remove(port.annotations().value(PORTNAME));
}
}
@@ -303,9 +329,9 @@
port.annotations().value(PORTNAME).startsWith(PORTNAME_PREFIX_ROUTER))
.forEach(vmPort -> {
OpenstackPort osPort = rulePopulator.openstackPort(vmPort);
- if (osPort != null) {
+ if (osPort != null && !osPort.deviceOwner().equals(DEVICE_OWNER_GATEWAY)) {
if (!doNotPushFlows) {
- rulePopulator.populateSwitchingRules(device, vmPort);
+ rulePopulator.populateSwitchingRules(doNotPushFlows, device, vmPort);
updatePortMap(device.id(), vmPort, networks, osPort);
}
registerDhcpInfo(osPort);
@@ -327,6 +353,7 @@
OpenstackPortInfo.Builder portBuilder = OpenstackPortInfo.builder()
.setDeviceId(deviceId)
.setHostIp((Ip4Address) openstackPort.fixedIps().values().stream().findFirst().orElse(null))
+ .setHostMac(openstackPort.macAddress())
.setVni(vni);
openstackPortInfoMap.putIfAbsent(port.annotations().value(PORTNAME),
diff --git a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/impl/OpenstackSwitchingRulePopulator.java b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/impl/OpenstackSwitchingRulePopulator.java
index 119e0ff..cc94c93 100644
--- a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/impl/OpenstackSwitchingRulePopulator.java
+++ b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/impl/OpenstackSwitchingRulePopulator.java
@@ -99,7 +99,10 @@
* @param device device to populate rules to
* @param port port for the VM created
*/
- public void populateSwitchingRules(Device device, Port port) {
+ public void populateSwitchingRules(boolean doNotPushFlow, Device device, Port port) {
+ if (doNotPushFlow) {
+ return;
+ }
populateFlowRulesForTunnelTag(device, port);
populateFlowRulesForTrafficToSameCnode(device, port);
populateFlowRulesForTrafficToDifferentCnode(device, port);
@@ -271,8 +274,11 @@
* @param removedPort removedport info
* @param openstackPortInfoMap openstackPortInfoMap
*/
- public void removeSwitchingRules(Port removedPort, Map<String, OpenstackPortInfo> openstackPortInfoMap) {
-
+ public void removeSwitchingRules(boolean doNotPushFlows, Port removedPort, Map<String,
+ OpenstackPortInfo> openstackPortInfoMap) {
+ if (doNotPushFlows) {
+ return;
+ }
OpenstackPortInfo openstackPortInfo = openstackPortInfoMap
.get(removedPort.annotations().value("portName"));
diff --git a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java
index 261128d..4e23753 100644
--- a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java
+++ b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/web/OpenstackPortWebResource.java
@@ -72,6 +72,9 @@
@Path("{portUUID}")
@DELETE
public Response deletePorts(@PathParam("portUUID") String id) {
+ OpenstackSwitchingService switchingService =
+ getService(OpenstackSwitchingService.class);
+ switchingService.deletePort(id);
return Response.status(Response.Status.OK).build();
}