Committed by
Ray Milkey
[ONOS-3697] Remove flow rules and dhcp mapping for router when it is removed.
Change-Id: I24e7c6d3fa0731822250c84ac5807f6192d371bf
Showing
4 changed files
with
63 additions
and
13 deletions
| ... | @@ -16,6 +16,7 @@ | ... | @@ -16,6 +16,7 @@ |
| 16 | package org.onosproject.openstackswitching.impl; | 16 | package org.onosproject.openstackswitching.impl; |
| 17 | 17 | ||
| 18 | import org.onlab.packet.Ip4Address; | 18 | import org.onlab.packet.Ip4Address; |
| 19 | +import org.onlab.packet.MacAddress; | ||
| 19 | import org.onosproject.net.DeviceId; | 20 | import org.onosproject.net.DeviceId; |
| 20 | 21 | ||
| 21 | import static com.google.common.base.Preconditions.checkNotNull; | 22 | import static com.google.common.base.Preconditions.checkNotNull; |
| ... | @@ -27,11 +28,13 @@ public final class OpenstackPortInfo { | ... | @@ -27,11 +28,13 @@ public final class OpenstackPortInfo { |
| 27 | 28 | ||
| 28 | private final Ip4Address hostIp; | 29 | private final Ip4Address hostIp; |
| 29 | private final DeviceId deviceId; | 30 | private final DeviceId deviceId; |
| 31 | + private final MacAddress hostMac; | ||
| 30 | private final long vni; | 32 | private final long vni; |
| 31 | 33 | ||
| 32 | - public OpenstackPortInfo(Ip4Address hostIp, DeviceId deviceId, | 34 | + public OpenstackPortInfo(Ip4Address hostIp, MacAddress hostMac, DeviceId deviceId, |
| 33 | long vni) { | 35 | long vni) { |
| 34 | this.hostIp = hostIp; | 36 | this.hostIp = hostIp; |
| 37 | + this.hostMac = hostMac; | ||
| 35 | this.deviceId = deviceId; | 38 | this.deviceId = deviceId; |
| 36 | this.vni = vni; | 39 | this.vni = vni; |
| 37 | } | 40 | } |
| ... | @@ -40,6 +43,10 @@ public final class OpenstackPortInfo { | ... | @@ -40,6 +43,10 @@ public final class OpenstackPortInfo { |
| 40 | return hostIp; | 43 | return hostIp; |
| 41 | } | 44 | } |
| 42 | 45 | ||
| 46 | + public MacAddress mac() { | ||
| 47 | + return hostMac; | ||
| 48 | + } | ||
| 49 | + | ||
| 43 | public DeviceId deviceId() { | 50 | public DeviceId deviceId() { |
| 44 | return deviceId; | 51 | return deviceId; |
| 45 | } | 52 | } |
| ... | @@ -54,6 +61,7 @@ public final class OpenstackPortInfo { | ... | @@ -54,6 +61,7 @@ public final class OpenstackPortInfo { |
| 54 | 61 | ||
| 55 | public static final class Builder { | 62 | public static final class Builder { |
| 56 | private Ip4Address hostIp; | 63 | private Ip4Address hostIp; |
| 64 | + private MacAddress hostMac; | ||
| 57 | private DeviceId deviceId; | 65 | private DeviceId deviceId; |
| 58 | private long vni; | 66 | private long vni; |
| 59 | 67 | ||
| ... | @@ -62,6 +70,11 @@ public final class OpenstackPortInfo { | ... | @@ -62,6 +70,11 @@ public final class OpenstackPortInfo { |
| 62 | return this; | 70 | return this; |
| 63 | } | 71 | } |
| 64 | 72 | ||
| 73 | + public Builder setHostMac(MacAddress hostMac) { | ||
| 74 | + this.hostMac = checkNotNull(hostMac, "hostMac cannot be bull"); | ||
| 75 | + return this; | ||
| 76 | + } | ||
| 77 | + | ||
| 65 | public Builder setDeviceId(DeviceId deviceId) { | 78 | public Builder setDeviceId(DeviceId deviceId) { |
| 66 | this.deviceId = checkNotNull(deviceId, "deviceId cannot be null"); | 79 | this.deviceId = checkNotNull(deviceId, "deviceId cannot be null"); |
| 67 | return this; | 80 | return this; |
| ... | @@ -78,6 +91,7 @@ public final class OpenstackPortInfo { | ... | @@ -78,6 +91,7 @@ public final class OpenstackPortInfo { |
| 78 | 91 | ||
| 79 | private OpenstackPortInfo(Builder builder) { | 92 | private OpenstackPortInfo(Builder builder) { |
| 80 | hostIp = builder.hostIp; | 93 | hostIp = builder.hostIp; |
| 94 | + hostMac = builder.hostMac; | ||
| 81 | deviceId = builder.deviceId; | 95 | deviceId = builder.deviceId; |
| 82 | vni = builder.vni; | 96 | vni = builder.vni; |
| 83 | } | 97 | } | ... | ... |
| ... | @@ -104,10 +104,12 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -104,10 +104,12 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
| 104 | protected DriverService driverService; | 104 | protected DriverService driverService; |
| 105 | 105 | ||
| 106 | public static final String PORTNAME_PREFIX_VM = "tap"; | 106 | public static final String PORTNAME_PREFIX_VM = "tap"; |
| 107 | - public static final String PORTNAME_PREFIX_ROUTER = "qr"; | 107 | + public static final String PORTNAME_PREFIX_ROUTER = "qr-"; |
| 108 | public static final String PORTNAME_PREFIX_TUNNEL = "vxlan"; | 108 | public static final String PORTNAME_PREFIX_TUNNEL = "vxlan"; |
| 109 | public static final String PORTNAME = "portName"; | 109 | public static final String PORTNAME = "portName"; |
| 110 | 110 | ||
| 111 | + public static final String DEVICE_OWNER_GATEWAY = "network:router_gateway"; | ||
| 112 | + | ||
| 111 | private ApplicationId appId; | 113 | private ApplicationId appId; |
| 112 | private boolean doNotPushFlows; | 114 | private boolean doNotPushFlows; |
| 113 | private Ip4Address neutronServer; | 115 | private Ip4Address neutronServer; |
| ... | @@ -170,14 +172,38 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -170,14 +172,38 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
| 170 | 172 | ||
| 171 | @Override | 173 | @Override |
| 172 | public void createPorts(OpenstackPort openstackPort) { | 174 | public void createPorts(OpenstackPort openstackPort) { |
| 173 | - if (!openstackPort.fixedIps().isEmpty()) { | 175 | + if (!openstackPort.fixedIps().isEmpty() |
| 176 | + && !openstackPort.deviceOwner().equals(DEVICE_OWNER_GATEWAY)) { | ||
| 174 | registerDhcpInfo(openstackPort); | 177 | registerDhcpInfo(openstackPort); |
| 175 | } | 178 | } |
| 176 | } | 179 | } |
| 177 | 180 | ||
| 178 | @Override | 181 | @Override |
| 179 | public void deletePort(String uuid) { | 182 | public void deletePort(String uuid) { |
| 180 | - | 183 | + // When VMs are remvoed, the flow rules for the VMs are removed using ONOS port update event. |
| 184 | + // But, when router is removed, no ONOS port event occurs and we need to use Neutron port event. | ||
| 185 | + // Here we should not touch any rules for VMs. | ||
| 186 | + log.debug("port {} was removed", uuid); | ||
| 187 | + | ||
| 188 | + String routerPortName = PORTNAME_PREFIX_ROUTER + uuid.substring(0, 11); | ||
| 189 | + OpenstackPortInfo routerPortInfo = openstackPortInfoMap.get(routerPortName); | ||
| 190 | + if (routerPortInfo != null) { | ||
| 191 | + dhcpService.removeStaticMapping(routerPortInfo.mac()); | ||
| 192 | + if (!doNotPushFlows) { | ||
| 193 | + deviceService.getPorts(routerPortInfo.deviceId()).forEach(port -> { | ||
| 194 | + String pName = port.annotations().value("portName"); | ||
| 195 | + if (pName.equals(routerPortName)) { | ||
| 196 | + OpenstackSwitchingRulePopulator rulePopulator = | ||
| 197 | + new OpenstackSwitchingRulePopulator(appId, flowObjectiveService, | ||
| 198 | + deviceService, restHandler, driverService); | ||
| 199 | + | ||
| 200 | + rulePopulator.removeSwitchingRules(doNotPushFlows, port, openstackPortInfoMap); | ||
| 201 | + openstackPortInfoMap.remove(routerPortName); | ||
| 202 | + return; | ||
| 203 | + } | ||
| 204 | + }); | ||
| 205 | + } | ||
| 206 | + } | ||
| 181 | } | 207 | } |
| 182 | 208 | ||
| 183 | @Override | 209 | @Override |
| ... | @@ -268,17 +294,17 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -268,17 +294,17 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
| 268 | OpenstackSwitchingRulePopulator rulePopulator = | 294 | OpenstackSwitchingRulePopulator rulePopulator = |
| 269 | new OpenstackSwitchingRulePopulator(appId, flowObjectiveService, | 295 | new OpenstackSwitchingRulePopulator(appId, flowObjectiveService, |
| 270 | deviceService, restHandler, driverService); | 296 | deviceService, restHandler, driverService); |
| 271 | - rulePopulator.populateSwitchingRules(device, port); | 297 | + rulePopulator.populateSwitchingRules(doNotPushFlows, device, port); |
| 272 | updatePortMap(device.id(), port, restHandler.getNetworks(), rulePopulator.openstackPort(port)); | 298 | updatePortMap(device.id(), port, restHandler.getNetworks(), rulePopulator.openstackPort(port)); |
| 273 | - | ||
| 274 | //In case portupdate event is driven by vm shutoff from openstack | 299 | //In case portupdate event is driven by vm shutoff from openstack |
| 275 | } else if (!port.isEnabled() && openstackPortInfoMap.containsKey(port.annotations().value(PORTNAME))) { | 300 | } else if (!port.isEnabled() && openstackPortInfoMap.containsKey(port.annotations().value(PORTNAME))) { |
| 276 | log.debug("Flowrules according to the port {} were removed", port.number().toString()); | 301 | log.debug("Flowrules according to the port {} were removed", port.number().toString()); |
| 277 | OpenstackSwitchingRulePopulator rulePopulator = | 302 | OpenstackSwitchingRulePopulator rulePopulator = |
| 278 | new OpenstackSwitchingRulePopulator(appId, flowObjectiveService, | 303 | new OpenstackSwitchingRulePopulator(appId, flowObjectiveService, |
| 279 | deviceService, restHandler, driverService); | 304 | deviceService, restHandler, driverService); |
| 280 | - openstackPortInfoMap.get(port.annotations().value(PORTNAME)); | 305 | + |
| 281 | - rulePopulator.removeSwitchingRules(port, openstackPortInfoMap); | 306 | + rulePopulator.removeSwitchingRules(doNotPushFlows, port, openstackPortInfoMap); |
| 307 | + dhcpService.removeStaticMapping(openstackPortInfoMap.get(port.annotations().value(PORTNAME)).mac()); | ||
| 282 | openstackPortInfoMap.remove(port.annotations().value(PORTNAME)); | 308 | openstackPortInfoMap.remove(port.annotations().value(PORTNAME)); |
| 283 | } | 309 | } |
| 284 | } | 310 | } |
| ... | @@ -303,9 +329,9 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -303,9 +329,9 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
| 303 | port.annotations().value(PORTNAME).startsWith(PORTNAME_PREFIX_ROUTER)) | 329 | port.annotations().value(PORTNAME).startsWith(PORTNAME_PREFIX_ROUTER)) |
| 304 | .forEach(vmPort -> { | 330 | .forEach(vmPort -> { |
| 305 | OpenstackPort osPort = rulePopulator.openstackPort(vmPort); | 331 | OpenstackPort osPort = rulePopulator.openstackPort(vmPort); |
| 306 | - if (osPort != null) { | 332 | + if (osPort != null && !osPort.deviceOwner().equals(DEVICE_OWNER_GATEWAY)) { |
| 307 | if (!doNotPushFlows) { | 333 | if (!doNotPushFlows) { |
| 308 | - rulePopulator.populateSwitchingRules(device, vmPort); | 334 | + rulePopulator.populateSwitchingRules(doNotPushFlows, device, vmPort); |
| 309 | updatePortMap(device.id(), vmPort, networks, osPort); | 335 | updatePortMap(device.id(), vmPort, networks, osPort); |
| 310 | } | 336 | } |
| 311 | registerDhcpInfo(osPort); | 337 | registerDhcpInfo(osPort); |
| ... | @@ -327,6 +353,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -327,6 +353,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
| 327 | OpenstackPortInfo.Builder portBuilder = OpenstackPortInfo.builder() | 353 | OpenstackPortInfo.Builder portBuilder = OpenstackPortInfo.builder() |
| 328 | .setDeviceId(deviceId) | 354 | .setDeviceId(deviceId) |
| 329 | .setHostIp((Ip4Address) openstackPort.fixedIps().values().stream().findFirst().orElse(null)) | 355 | .setHostIp((Ip4Address) openstackPort.fixedIps().values().stream().findFirst().orElse(null)) |
| 356 | + .setHostMac(openstackPort.macAddress()) | ||
| 330 | .setVni(vni); | 357 | .setVni(vni); |
| 331 | 358 | ||
| 332 | openstackPortInfoMap.putIfAbsent(port.annotations().value(PORTNAME), | 359 | openstackPortInfoMap.putIfAbsent(port.annotations().value(PORTNAME), | ... | ... |
| ... | @@ -99,7 +99,10 @@ public class OpenstackSwitchingRulePopulator { | ... | @@ -99,7 +99,10 @@ public class OpenstackSwitchingRulePopulator { |
| 99 | * @param device device to populate rules to | 99 | * @param device device to populate rules to |
| 100 | * @param port port for the VM created | 100 | * @param port port for the VM created |
| 101 | */ | 101 | */ |
| 102 | - public void populateSwitchingRules(Device device, Port port) { | 102 | + public void populateSwitchingRules(boolean doNotPushFlow, Device device, Port port) { |
| 103 | + if (doNotPushFlow) { | ||
| 104 | + return; | ||
| 105 | + } | ||
| 103 | populateFlowRulesForTunnelTag(device, port); | 106 | populateFlowRulesForTunnelTag(device, port); |
| 104 | populateFlowRulesForTrafficToSameCnode(device, port); | 107 | populateFlowRulesForTrafficToSameCnode(device, port); |
| 105 | populateFlowRulesForTrafficToDifferentCnode(device, port); | 108 | populateFlowRulesForTrafficToDifferentCnode(device, port); |
| ... | @@ -271,8 +274,11 @@ public class OpenstackSwitchingRulePopulator { | ... | @@ -271,8 +274,11 @@ public class OpenstackSwitchingRulePopulator { |
| 271 | * @param removedPort removedport info | 274 | * @param removedPort removedport info |
| 272 | * @param openstackPortInfoMap openstackPortInfoMap | 275 | * @param openstackPortInfoMap openstackPortInfoMap |
| 273 | */ | 276 | */ |
| 274 | - public void removeSwitchingRules(Port removedPort, Map<String, OpenstackPortInfo> openstackPortInfoMap) { | 277 | + public void removeSwitchingRules(boolean doNotPushFlows, Port removedPort, Map<String, |
| 275 | - | 278 | + OpenstackPortInfo> openstackPortInfoMap) { |
| 279 | + if (doNotPushFlows) { | ||
| 280 | + return; | ||
| 281 | + } | ||
| 276 | OpenstackPortInfo openstackPortInfo = openstackPortInfoMap | 282 | OpenstackPortInfo openstackPortInfo = openstackPortInfoMap |
| 277 | .get(removedPort.annotations().value("portName")); | 283 | .get(removedPort.annotations().value("portName")); |
| 278 | 284 | ... | ... |
| ... | @@ -72,6 +72,9 @@ public class OpenstackPortWebResource extends AbstractWebResource { | ... | @@ -72,6 +72,9 @@ public class OpenstackPortWebResource extends AbstractWebResource { |
| 72 | @Path("{portUUID}") | 72 | @Path("{portUUID}") |
| 73 | @DELETE | 73 | @DELETE |
| 74 | public Response deletePorts(@PathParam("portUUID") String id) { | 74 | public Response deletePorts(@PathParam("portUUID") String id) { |
| 75 | + OpenstackSwitchingService switchingService = | ||
| 76 | + getService(OpenstackSwitchingService.class); | ||
| 77 | + switchingService.deletePort(id); | ||
| 75 | return Response.status(Response.Status.OK).build(); | 78 | return Response.status(Response.Status.OK).build(); |
| 76 | } | 79 | } |
| 77 | 80 | ... | ... |
-
Please register or login to post a comment