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
62 additions
and
12 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) { |
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); | ||
180 | 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