Committed by
Gerrit Code Review
[ONOS-4205] support east-west routing in openstackRouting
- Supports east-west routing traffic - Fixes javadocs Change-Id: I23d9b9497cc2be667fbc9554812c7f5b49c35364
Showing
3 changed files
with
292 additions
and
55 deletions
... | @@ -20,71 +20,78 @@ import org.onosproject.openstackinterface.OpenstackRouter; | ... | @@ -20,71 +20,78 @@ import org.onosproject.openstackinterface.OpenstackRouter; |
20 | import org.onosproject.openstackinterface.OpenstackRouterInterface; | 20 | import org.onosproject.openstackinterface.OpenstackRouterInterface; |
21 | 21 | ||
22 | /** | 22 | /** |
23 | - * The Interface of Openstack Routing. | 23 | + * Supports L3 management REST API for openstack. |
24 | */ | 24 | */ |
25 | public interface OpenstackRoutingService { | 25 | public interface OpenstackRoutingService { |
26 | 26 | ||
27 | /** | 27 | /** |
28 | - * Stores the Floating IP information created by Openstack. | 28 | + * Stores the floating IP information created by openstack. |
29 | * | 29 | * |
30 | - * @param openstackFloatingIP Floating IP information | 30 | + * @param openstackFloatingIp Floating IP information |
31 | */ | 31 | */ |
32 | - void createFloatingIP(OpenstackFloatingIP openstackFloatingIP); | 32 | + void createFloatingIP(OpenstackFloatingIP openstackFloatingIp); |
33 | 33 | ||
34 | /** | 34 | /** |
35 | - * Updates flow rules corresponding to the Floating IP information updated by Openstack. | 35 | + * Updates flow rules corresponding to the floating IP information updated by openstack. |
36 | * | 36 | * |
37 | - * @param openstackFloatingIP Floating IP information | 37 | + * @param openstackFloatingIp Floating IP information |
38 | */ | 38 | */ |
39 | - void updateFloatingIP(OpenstackFloatingIP openstackFloatingIP); | 39 | + void updateFloatingIP(OpenstackFloatingIP openstackFloatingIp); |
40 | 40 | ||
41 | /** | 41 | /** |
42 | - * Removes flow rules corresponding to Floating IP information removed by Openstack. | 42 | + * Removes flow rules corresponding to floating IP information removed by openstack. |
43 | * | 43 | * |
44 | * @param id Deleted Floating IP`s ID | 44 | * @param id Deleted Floating IP`s ID |
45 | */ | 45 | */ |
46 | void deleteFloatingIP(String id); | 46 | void deleteFloatingIP(String id); |
47 | 47 | ||
48 | /** | 48 | /** |
49 | - * Stores the router information created by Openstack. | 49 | + * Stores the router information created by openstack. |
50 | * | 50 | * |
51 | - * @param openstackRouter Floating IP information | 51 | + * @param openstackRouter Router information |
52 | */ | 52 | */ |
53 | void createRouter(OpenstackRouter openstackRouter); | 53 | void createRouter(OpenstackRouter openstackRouter); |
54 | 54 | ||
55 | /** | 55 | /** |
56 | - * Updates flow rules corresponding to the router information updated by Openstack. | 56 | + * Updates flow rules corresponding to the router information updated by openstack. |
57 | * | 57 | * |
58 | * @param openstackRouter Router information | 58 | * @param openstackRouter Router information |
59 | */ | 59 | */ |
60 | void updateRouter(OpenstackRouter openstackRouter); | 60 | void updateRouter(OpenstackRouter openstackRouter); |
61 | 61 | ||
62 | /** | 62 | /** |
63 | - * Removes flow rules corresponding to the router information removed by Openstack. | 63 | + * Removes flow rules corresponding to the router information removed by openstack. |
64 | * | 64 | * |
65 | * @param id Deleted router`s ID | 65 | * @param id Deleted router`s ID |
66 | */ | 66 | */ |
67 | void deleteRouter(String id); | 67 | void deleteRouter(String id); |
68 | 68 | ||
69 | /** | 69 | /** |
70 | - * Updates flow rules corresponding to the router information updated by Openstack. | 70 | + * Updates flow rules corresponding to the router information updated by openstack. |
71 | * | 71 | * |
72 | - * @param openstackRouterInterface Router information | 72 | + * @param openstackRouterInterface Router interface information |
73 | */ | 73 | */ |
74 | void updateRouterInterface(OpenstackRouterInterface openstackRouterInterface); | 74 | void updateRouterInterface(OpenstackRouterInterface openstackRouterInterface); |
75 | 75 | ||
76 | /** | 76 | /** |
77 | - * Removes flow rules corresponding to the router information removed by Openstack. | 77 | + * Removes flow rules corresponding to the router information removed by openstack. |
78 | * | 78 | * |
79 | - * @param openstackRouterInterface Router information | 79 | + * @param openstackRouterInterface Router interface information |
80 | */ | 80 | */ |
81 | void removeRouterInterface(OpenstackRouterInterface openstackRouterInterface); | 81 | void removeRouterInterface(OpenstackRouterInterface openstackRouterInterface); |
82 | 82 | ||
83 | /** | 83 | /** |
84 | - * Checks floatingIp deassociation when corresponding deleted vm. | 84 | + * Checks floatingIp disassociation when corresponding deleted vm. |
85 | * | 85 | * |
86 | * @param portId Deleted vm | 86 | * @param portId Deleted vm |
87 | * @param portInfo stored information about deleted vm | 87 | * @param portInfo stored information about deleted vm |
88 | */ | 88 | */ |
89 | void checkDisassociatedFloatingIp(String portId, OpenstackPortInfo portInfo); | 89 | void checkDisassociatedFloatingIp(String portId, OpenstackPortInfo portInfo); |
90 | + | ||
91 | + /** | ||
92 | + * Returns network id for routerInterface. | ||
93 | + * | ||
94 | + * @param portId routerInterface`s port id | ||
95 | + */ | ||
96 | + String networkIdForRouterInterface(String portId); | ||
90 | } | 97 | } | ... | ... |
... | @@ -37,6 +37,8 @@ import org.onosproject.net.config.NetworkConfigEvent; | ... | @@ -37,6 +37,8 @@ import org.onosproject.net.config.NetworkConfigEvent; |
37 | import org.onosproject.net.config.NetworkConfigListener; | 37 | import org.onosproject.net.config.NetworkConfigListener; |
38 | import org.onosproject.net.config.NetworkConfigRegistry; | 38 | import org.onosproject.net.config.NetworkConfigRegistry; |
39 | import org.onosproject.net.config.NetworkConfigService; | 39 | import org.onosproject.net.config.NetworkConfigService; |
40 | +import org.onosproject.net.device.DeviceEvent; | ||
41 | +import org.onosproject.net.device.DeviceListener; | ||
40 | import org.onosproject.net.device.DeviceService; | 42 | import org.onosproject.net.device.DeviceService; |
41 | import org.onosproject.net.driver.DriverService; | 43 | import org.onosproject.net.driver.DriverService; |
42 | import org.onosproject.net.flowobjective.FlowObjectiveService; | 44 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
... | @@ -115,12 +117,15 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -115,12 +117,15 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
115 | private ApplicationId appId; | 117 | private ApplicationId appId; |
116 | private ConsistentMap<Integer, String> tpPortNumMap; // Map<PortNum, allocated VM`s Mac & destionation Ip address> | 118 | private ConsistentMap<Integer, String> tpPortNumMap; // Map<PortNum, allocated VM`s Mac & destionation Ip address> |
117 | private ConsistentMap<String, OpenstackFloatingIP> floatingIpMap; // Map<FloatingIp`s Id, FloatingIp object> | 119 | private ConsistentMap<String, OpenstackFloatingIP> floatingIpMap; // Map<FloatingIp`s Id, FloatingIp object> |
120 | + // Map<RouterInterface`s portId, Corresponded port`s network id> | ||
121 | + private ConsistentMap<String, String> routerInterfaceMap; | ||
118 | private static final String APP_ID = "org.onosproject.openstackrouting"; | 122 | private static final String APP_ID = "org.onosproject.openstackrouting"; |
119 | private static final String PORT_NAME = "portName"; | 123 | private static final String PORT_NAME = "portName"; |
120 | private static final String PORTNAME_PREFIX_VM = "tap"; | 124 | private static final String PORTNAME_PREFIX_VM = "tap"; |
121 | private static final String DEVICE_OWNER_ROUTER_INTERFACE = "network:router_interface"; | 125 | private static final String DEVICE_OWNER_ROUTER_INTERFACE = "network:router_interface"; |
122 | private static final String FLOATING_IP_MAP_NAME = "openstackrouting-floatingip"; | 126 | private static final String FLOATING_IP_MAP_NAME = "openstackrouting-floatingip"; |
123 | - private static final String TP_PORT_MAP_NAME = "openstackrouting-portnum"; | 127 | + private static final String TP_PORT_MAP_NAME = "openstackrouting-tpportnum"; |
128 | + private static final String ROUTER_INTERFACE_MAP_NAME = "openstackrouting-routerinterface"; | ||
124 | private static final String COLON = ":"; | 129 | private static final String COLON = ":"; |
125 | private static final int PNAT_PORT_EXPIRE_TIME = 1200 * 1000; | 130 | private static final int PNAT_PORT_EXPIRE_TIME = 1200 * 1000; |
126 | private static final int TP_PORT_MINIMUM_NUM = 1024; | 131 | private static final int TP_PORT_MINIMUM_NUM = 1024; |
... | @@ -152,7 +157,13 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -152,7 +157,13 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
152 | .register(Integer.class) | 157 | .register(Integer.class) |
153 | .register(String.class); | 158 | .register(String.class); |
154 | 159 | ||
160 | + private static final KryoNamespace.Builder ROUTER_INTERFACE_SERIALIZER = KryoNamespace.newBuilder() | ||
161 | + .register(KryoNamespaces.API) | ||
162 | + .register(KryoNamespaces.MISC) | ||
163 | + .register(String.class); | ||
164 | + | ||
155 | private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor(); | 165 | private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor(); |
166 | + private InternalDeviceListener internalDeviceListener = new InternalDeviceListener(); | ||
156 | private ExecutorService l3EventExecutorService = | 167 | private ExecutorService l3EventExecutorService = |
157 | Executors.newSingleThreadExecutor(groupedThreads("onos/openstackrouting", "L3-event")); | 168 | Executors.newSingleThreadExecutor(groupedThreads("onos/openstackrouting", "L3-event")); |
158 | private ExecutorService icmpEventExecutorService = | 169 | private ExecutorService icmpEventExecutorService = |
... | @@ -170,6 +181,7 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -170,6 +181,7 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
170 | packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1)); | 181 | packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1)); |
171 | configRegistry.registerConfigFactory(configFactory); | 182 | configRegistry.registerConfigFactory(configFactory); |
172 | configService.addListener(configListener); | 183 | configService.addListener(configListener); |
184 | + deviceService.addListener(internalDeviceListener); | ||
173 | 185 | ||
174 | floatingIpMap = storageService.<String, OpenstackFloatingIP>consistentMapBuilder() | 186 | floatingIpMap = storageService.<String, OpenstackFloatingIP>consistentMapBuilder() |
175 | .withSerializer(Serializer.using(FLOATING_IP_SERIALIZER.build())) | 187 | .withSerializer(Serializer.using(FLOATING_IP_SERIALIZER.build())) |
... | @@ -181,52 +193,59 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -181,52 +193,59 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
181 | .withName(TP_PORT_MAP_NAME) | 193 | .withName(TP_PORT_MAP_NAME) |
182 | .withApplicationId(appId) | 194 | .withApplicationId(appId) |
183 | .build(); | 195 | .build(); |
196 | + routerInterfaceMap = storageService.<String, String>consistentMapBuilder() | ||
197 | + .withSerializer(Serializer.using(ROUTER_INTERFACE_SERIALIZER.build())) | ||
198 | + .withName(ROUTER_INTERFACE_MAP_NAME) | ||
199 | + .withApplicationId(appId) | ||
200 | + .build(); | ||
184 | 201 | ||
185 | readConfiguration(); | 202 | readConfiguration(); |
186 | 203 | ||
187 | - log.info("onos-openstackrouting started"); | 204 | + log.info("started"); |
188 | } | 205 | } |
189 | 206 | ||
190 | @Deactivate | 207 | @Deactivate |
191 | protected void deactivate() { | 208 | protected void deactivate() { |
192 | packetService.removeProcessor(internalPacketProcessor); | 209 | packetService.removeProcessor(internalPacketProcessor); |
210 | + deviceService.removeListener(internalDeviceListener); | ||
193 | l3EventExecutorService.shutdown(); | 211 | l3EventExecutorService.shutdown(); |
194 | icmpEventExecutorService.shutdown(); | 212 | icmpEventExecutorService.shutdown(); |
195 | arpEventExecutorService.shutdown(); | 213 | arpEventExecutorService.shutdown(); |
196 | 214 | ||
197 | floatingIpMap.clear(); | 215 | floatingIpMap.clear(); |
198 | tpPortNumMap.clear(); | 216 | tpPortNumMap.clear(); |
217 | + routerInterfaceMap.clear(); | ||
199 | 218 | ||
200 | - log.info("onos-openstackrouting stopped"); | 219 | + log.info("stopped"); |
201 | } | 220 | } |
202 | 221 | ||
203 | 222 | ||
204 | @Override | 223 | @Override |
205 | - public void createFloatingIP(OpenstackFloatingIP openstackFloatingIP) { | 224 | + public void createFloatingIP(OpenstackFloatingIP openstackFloatingIp) { |
206 | - floatingIpMap.put(openstackFloatingIP.id(), openstackFloatingIP); | 225 | + floatingIpMap.put(openstackFloatingIp.id(), openstackFloatingIp); |
207 | } | 226 | } |
208 | 227 | ||
209 | @Override | 228 | @Override |
210 | - public void updateFloatingIP(OpenstackFloatingIP openstackFloatingIP) { | 229 | + public void updateFloatingIP(OpenstackFloatingIP openstackFloatingIp) { |
211 | - if (!floatingIpMap.containsKey(openstackFloatingIP.id())) { | 230 | + if (!floatingIpMap.containsKey(openstackFloatingIp.id())) { |
212 | - log.warn("There`s no information about {} in FloatingIpMap", openstackFloatingIP.id()); | 231 | + log.warn("There`s no information about {} in FloatingIpMap", openstackFloatingIp.id()); |
213 | return; | 232 | return; |
214 | } | 233 | } |
215 | - if (openstackFloatingIP.portId() == null || openstackFloatingIP.portId().equals("null")) { | 234 | + if (openstackFloatingIp.portId() == null || openstackFloatingIp.portId().equals("null")) { |
216 | - OpenstackFloatingIP floatingIP = floatingIpMap.get(openstackFloatingIP.id()).value(); | 235 | + OpenstackFloatingIP floatingIp = floatingIpMap.get(openstackFloatingIp.id()).value(); |
217 | OpenstackPortInfo portInfo = openstackSwitchingService.openstackPortInfo() | 236 | OpenstackPortInfo portInfo = openstackSwitchingService.openstackPortInfo() |
218 | - .get(PORTNAME_PREFIX_VM.concat(floatingIP.portId().substring(0, 11))); | 237 | + .get(PORTNAME_PREFIX_VM.concat(floatingIp.portId().substring(0, 11))); |
219 | if (portInfo == null) { | 238 | if (portInfo == null) { |
220 | - log.warn("There`s no portInfo information about portId {}", floatingIP.portId()); | 239 | + log.warn("There`s no portInfo information about portId {}", floatingIp.portId()); |
221 | return; | 240 | return; |
222 | } | 241 | } |
223 | l3EventExecutorService.execute( | 242 | l3EventExecutorService.execute( |
224 | - new OpenstackFloatingIPHandler(rulePopulator, floatingIP, false, portInfo)); | 243 | + new OpenstackFloatingIPHandler(rulePopulator, floatingIp, false, portInfo)); |
225 | - floatingIpMap.replace(floatingIP.id(), openstackFloatingIP); | 244 | + floatingIpMap.replace(floatingIp.id(), openstackFloatingIp); |
226 | } else { | 245 | } else { |
227 | - floatingIpMap.put(openstackFloatingIP.id(), openstackFloatingIP); | 246 | + floatingIpMap.put(openstackFloatingIp.id(), openstackFloatingIp); |
228 | l3EventExecutorService.execute( | 247 | l3EventExecutorService.execute( |
229 | - new OpenstackFloatingIPHandler(rulePopulator, openstackFloatingIP, true, null)); | 248 | + new OpenstackFloatingIPHandler(rulePopulator, openstackFloatingIp, true, null)); |
230 | } | 249 | } |
231 | } | 250 | } |
232 | 251 | ||
... | @@ -280,11 +299,69 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -280,11 +299,69 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
280 | List<OpenstackRouterInterface> routerInterfaces = Lists.newArrayList(); | 299 | List<OpenstackRouterInterface> routerInterfaces = Lists.newArrayList(); |
281 | routerInterfaces.add(routerInterface); | 300 | routerInterfaces.add(routerInterface); |
282 | checkExternalConnection(getOpenstackRouter(routerInterface.id()), routerInterfaces); | 301 | checkExternalConnection(getOpenstackRouter(routerInterface.id()), routerInterfaces); |
302 | + setL3Connection(getOpenstackRouter(routerInterface.id()), null); | ||
303 | + routerInterfaceMap.put(routerInterface.portId(), openstackService.port(routerInterface.portId()).networkId()); | ||
304 | + } | ||
305 | + | ||
306 | + private void setL3Connection(OpenstackRouter openstackRouter, OpenstackPort openstackPort) { | ||
307 | + Collection<OpenstackRouterInterface> interfaceList = getOpenstackRouterInterface(openstackRouter); | ||
308 | + if (interfaceList.size() < 2) { | ||
309 | + return; | ||
310 | + } | ||
311 | + if (openstackPort == null) { | ||
312 | + interfaceList.forEach(i -> { | ||
313 | + OpenstackPort interfacePort = openstackService.port(i.portId()); | ||
314 | + openstackService.ports() | ||
315 | + .stream() | ||
316 | + .filter(p -> p.networkId().equals(interfacePort.networkId()) | ||
317 | + && !p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)) | ||
318 | + .forEach(p -> rulePopulator.populateL3Rules(p, | ||
319 | + getL3ConnectionList(p.networkId(), interfaceList))); | ||
320 | + }); | ||
321 | + } else { | ||
322 | + rulePopulator.populateL3Rules(openstackPort, getL3ConnectionList(openstackPort.networkId(), interfaceList)); | ||
323 | + } | ||
324 | + | ||
325 | + } | ||
326 | + | ||
327 | + private List<OpenstackRouterInterface> getL3ConnectionList(String networkId, | ||
328 | + Collection<OpenstackRouterInterface> interfaceList) { | ||
329 | + List<OpenstackRouterInterface> targetList = Lists.newArrayList(); | ||
330 | + interfaceList.forEach(i -> { | ||
331 | + OpenstackPort port = openstackService.port(i.portId()); | ||
332 | + if (!port.networkId().equals(networkId)) { | ||
333 | + targetList.add(i); | ||
334 | + } | ||
335 | + }); | ||
336 | + return targetList; | ||
283 | } | 337 | } |
284 | 338 | ||
285 | @Override | 339 | @Override |
286 | public void removeRouterInterface(OpenstackRouterInterface routerInterface) { | 340 | public void removeRouterInterface(OpenstackRouterInterface routerInterface) { |
341 | + OpenstackRouter router = openstackService.router(routerInterface.id()); | ||
342 | + Collection<OpenstackRouterInterface> interfaceList = getOpenstackRouterInterface(router); | ||
343 | + if (interfaceList.size() == 1) { | ||
344 | + List<OpenstackRouterInterface> newList = Lists.newArrayList(); | ||
345 | + newList.add(routerInterface); | ||
346 | + interfaceList.forEach(i -> removeL3RulesForRouterInterface(i, router, newList)); | ||
347 | + } | ||
348 | + removeL3RulesForRouterInterface(routerInterface, router, null); | ||
287 | rulePopulator.removeExternalRules(routerInterface); | 349 | rulePopulator.removeExternalRules(routerInterface); |
350 | + routerInterfaceMap.remove(routerInterface.portId()); | ||
351 | + } | ||
352 | + | ||
353 | + private void removeL3RulesForRouterInterface(OpenstackRouterInterface routerInterface, OpenstackRouter router, | ||
354 | + List<OpenstackRouterInterface> newList) { | ||
355 | + openstackService.ports(routerInterfaceMap.get(routerInterface.portId()).value()).forEach(p -> { | ||
356 | + Ip4Address vmIp = (Ip4Address) p.fixedIps().values().toArray()[0]; | ||
357 | + if (newList == null) { | ||
358 | + rulePopulator.removeL3Rules(vmIp, | ||
359 | + getL3ConnectionList(p.networkId(), getOpenstackRouterInterface(router))); | ||
360 | + } else { | ||
361 | + rulePopulator.removeL3Rules(vmIp, newList); | ||
362 | + } | ||
363 | + } | ||
364 | + ); | ||
288 | } | 365 | } |
289 | 366 | ||
290 | @Override | 367 | @Override |
... | @@ -313,6 +390,11 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -313,6 +390,11 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
313 | } | 390 | } |
314 | } | 391 | } |
315 | 392 | ||
393 | + @Override | ||
394 | + public String networkIdForRouterInterface(String portId) { | ||
395 | + return routerInterfaceMap.get(portId).value(); | ||
396 | + } | ||
397 | + | ||
316 | private Collection<OpenstackFloatingIP> associatedFloatingIps() { | 398 | private Collection<OpenstackFloatingIP> associatedFloatingIps() { |
317 | List<OpenstackFloatingIP> fIps = Lists.newArrayList(); | 399 | List<OpenstackFloatingIP> fIps = Lists.newArrayList(); |
318 | floatingIpMap.values() | 400 | floatingIpMap.values() |
... | @@ -327,10 +409,7 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -327,10 +409,7 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
327 | openstackService.ports() | 409 | openstackService.ports() |
328 | .stream() | 410 | .stream() |
329 | .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)) | 411 | .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)) |
330 | - .forEach(p -> { | 412 | + .forEach(p -> updateRouterInterface(portToRouterInterface(p))) |
331 | - OpenstackRouterInterface routerInterface = portToRouterInterface(p); | ||
332 | - updateRouterInterface(routerInterface); | ||
333 | - }) | ||
334 | ); | 413 | ); |
335 | 414 | ||
336 | } | 415 | } |
... | @@ -382,14 +461,13 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -382,14 +461,13 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
382 | int portNum = getPortNum(ethernet.getSourceMAC(), iPacket.getDestinationAddress()); | 461 | int portNum = getPortNum(ethernet.getSourceMAC(), iPacket.getDestinationAddress()); |
383 | Optional<Port> port = | 462 | Optional<Port> port = |
384 | getExternalPort(pkt.receivedFrom().deviceId(), config.gatewayExternalInterfaceName()); | 463 | getExternalPort(pkt.receivedFrom().deviceId(), config.gatewayExternalInterfaceName()); |
385 | - | 464 | + if (port.isPresent()) { |
386 | - if (!port.isPresent()) { | ||
387 | - log.warn("There`s no external interface"); | ||
388 | - } else { | ||
389 | OpenstackPort openstackPort = getOpenstackPort(ethernet.getSourceMAC(), | 465 | OpenstackPort openstackPort = getOpenstackPort(ethernet.getSourceMAC(), |
390 | Ip4Address.valueOf(iPacket.getSourceAddress())); | 466 | Ip4Address.valueOf(iPacket.getSourceAddress())); |
391 | l3EventExecutorService.execute(new OpenstackPnatHandler(rulePopulator, context, | 467 | l3EventExecutorService.execute(new OpenstackPnatHandler(rulePopulator, context, |
392 | portNum, openstackPort, port.get(), config)); | 468 | portNum, openstackPort, port.get(), config)); |
469 | + } else { | ||
470 | + log.warn("There`s no external interface"); | ||
393 | } | 471 | } |
394 | break; | 472 | break; |
395 | } | 473 | } |
... | @@ -471,22 +549,20 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -471,22 +549,20 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
471 | List<OpenstackRouterInterface> interfaces = Lists.newArrayList(); | 549 | List<OpenstackRouterInterface> interfaces = Lists.newArrayList(); |
472 | openstackService.ports() | 550 | openstackService.ports() |
473 | .stream() | 551 | .stream() |
474 | - .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)) | 552 | + .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE) |
475 | - .filter(p -> p.deviceId().equals(router.id())) | 553 | + && p.deviceId().equals(router.id())) |
476 | - .forEach(p -> { | 554 | + .forEach(p -> interfaces.add(portToRouterInterface(p))); |
477 | - interfaces.add(portToRouterInterface(p)); | ||
478 | - }); | ||
479 | return interfaces; | 555 | return interfaces; |
480 | } | 556 | } |
481 | 557 | ||
482 | private OpenstackRouter getOpenstackRouter(String id) { | 558 | private OpenstackRouter getOpenstackRouter(String id) { |
483 | return openstackService.routers().stream().filter(r -> | 559 | return openstackService.routers().stream().filter(r -> |
484 | - r.id().equals(id)).findAny().orElse(null); | 560 | + r.id().equals(id)).iterator().next(); |
485 | } | 561 | } |
486 | 562 | ||
487 | private OpenstackPort getOpenstackPort(MacAddress sourceMac, Ip4Address ip4Address) { | 563 | private OpenstackPort getOpenstackPort(MacAddress sourceMac, Ip4Address ip4Address) { |
488 | OpenstackPort openstackPort = openstackService.ports().stream() | 564 | OpenstackPort openstackPort = openstackService.ports().stream() |
489 | - .filter(p -> p.macAddress().equals(sourceMac)).findFirst().orElse(null); | 565 | + .filter(p -> p.macAddress().equals(sourceMac)).iterator().next(); |
490 | return openstackPort.fixedIps().values().stream().filter(ip -> | 566 | return openstackPort.fixedIps().values().stream().filter(ip -> |
491 | ip.equals(ip4Address)).count() > 0 ? openstackPort : null; | 567 | ip.equals(ip4Address)).count() > 0 ? openstackPort : null; |
492 | } | 568 | } |
... | @@ -534,4 +610,38 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -534,4 +610,38 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
534 | } | 610 | } |
535 | } | 611 | } |
536 | } | 612 | } |
613 | + | ||
614 | + private class InternalDeviceListener implements DeviceListener { | ||
615 | + | ||
616 | + @Override | ||
617 | + public void event(DeviceEvent deviceEvent) { | ||
618 | + if (deviceEvent.type() == DeviceEvent.Type.PORT_UPDATED) { | ||
619 | + Port port = deviceEvent.port(); | ||
620 | + OpenstackPortInfo portInfo = openstackSwitchingService.openstackPortInfo() | ||
621 | + .get(port.annotations().value(PORT_NAME)); | ||
622 | + OpenstackPort openstackPort = openstackService.port(port); | ||
623 | + OpenstackPort interfacePort = openstackService.ports() | ||
624 | + .stream() | ||
625 | + .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE) | ||
626 | + && p.networkId().equals(openstackPort.networkId())) | ||
627 | + .findAny() | ||
628 | + .orElse(null); | ||
629 | + if (portInfo == null && openstackPort == null) { | ||
630 | + log.warn("As delete event timing issue between routing and switching, Can`t delete L3 rules"); | ||
631 | + return; | ||
632 | + } | ||
633 | + if ((port.isEnabled()) && (interfacePort != null)) { | ||
634 | + OpenstackRouterInterface routerInterface = portToRouterInterface(interfacePort); | ||
635 | + l3EventExecutorService.execute(() -> | ||
636 | + setL3Connection(getOpenstackRouter(routerInterface.id()), openstackPort)); | ||
637 | + } else if (interfacePort != null) { | ||
638 | + OpenstackRouterInterface routerInterface = portToRouterInterface(interfacePort); | ||
639 | + l3EventExecutorService.execute(() -> rulePopulator.removeL3Rules(portInfo.ip(), | ||
640 | + getL3ConnectionList(portInfo.networkId(), | ||
641 | + getOpenstackRouterInterface(getOpenstackRouter(routerInterface.id()))))); | ||
642 | + } | ||
643 | + } | ||
644 | + } | ||
645 | + } | ||
646 | + | ||
537 | } | 647 | } | ... | ... |
... | @@ -54,12 +54,15 @@ import org.onosproject.openstackinterface.OpenstackSubnet; | ... | @@ -54,12 +54,15 @@ import org.onosproject.openstackinterface.OpenstackSubnet; |
54 | import org.onosproject.openstackinterface.OpenstackFloatingIP; | 54 | import org.onosproject.openstackinterface.OpenstackFloatingIP; |
55 | import org.onosproject.openstacknetworking.OpenstackNetworkingConfig; | 55 | import org.onosproject.openstacknetworking.OpenstackNetworkingConfig; |
56 | import org.onosproject.openstacknetworking.OpenstackPortInfo; | 56 | import org.onosproject.openstacknetworking.OpenstackPortInfo; |
57 | +import org.onosproject.openstacknetworking.OpenstackRoutingService; | ||
57 | import org.slf4j.Logger; | 58 | import org.slf4j.Logger; |
58 | import org.slf4j.LoggerFactory; | 59 | import org.slf4j.LoggerFactory; |
59 | 60 | ||
61 | +import java.util.List; | ||
60 | import java.util.stream.StreamSupport; | 62 | import java.util.stream.StreamSupport; |
61 | 63 | ||
62 | import static com.google.common.base.Preconditions.checkNotNull; | 64 | import static com.google.common.base.Preconditions.checkNotNull; |
65 | +import static org.onlab.osgi.DefaultServiceDirectory.getService; | ||
63 | 66 | ||
64 | /** | 67 | /** |
65 | * Populates Routing Flow Rules. | 68 | * Populates Routing Flow Rules. |
... | @@ -99,11 +102,11 @@ public class OpenstackRoutingRulePopulator { | ... | @@ -99,11 +102,11 @@ public class OpenstackRoutingRulePopulator { |
99 | * The constructor of openstackRoutingRulePopulator. | 102 | * The constructor of openstackRoutingRulePopulator. |
100 | * | 103 | * |
101 | * @param appId Caller`s appId | 104 | * @param appId Caller`s appId |
102 | - * @param openstackService OpenstackNetworkingService | 105 | + * @param openstackService Opestack REST request handler |
103 | * @param flowObjectiveService FlowObjectiveService | 106 | * @param flowObjectiveService FlowObjectiveService |
104 | * @param deviceService DeviceService | 107 | * @param deviceService DeviceService |
105 | * @param driverService DriverService | 108 | * @param driverService DriverService |
106 | - * @param config OpenstackRoutingConfig | 109 | + * @param config Configuration for openstack environment |
107 | */ | 110 | */ |
108 | public OpenstackRoutingRulePopulator(ApplicationId appId, OpenstackInterfaceService openstackService, | 111 | public OpenstackRoutingRulePopulator(ApplicationId appId, OpenstackInterfaceService openstackService, |
109 | FlowObjectiveService flowObjectiveService, DeviceService deviceService, | 112 | FlowObjectiveService flowObjectiveService, DeviceService deviceService, |
... | @@ -187,6 +190,7 @@ public class OpenstackRoutingRulePopulator { | ... | @@ -187,6 +190,7 @@ public class OpenstackRoutingRulePopulator { |
187 | .add(); | 190 | .add(); |
188 | 191 | ||
189 | flowObjectiveService.forward(inboundPacket.receivedFrom().deviceId(), fo); | 192 | flowObjectiveService.forward(inboundPacket.receivedFrom().deviceId(), fo); |
193 | + | ||
190 | } | 194 | } |
191 | 195 | ||
192 | private Port getPortOfExternalInterface() { | 196 | private Port getPortOfExternalInterface() { |
... | @@ -252,8 +256,8 @@ public class OpenstackRoutingRulePopulator { | ... | @@ -252,8 +256,8 @@ public class OpenstackRoutingRulePopulator { |
252 | String openstackPortName = PORTNAME_PREFIX_VM + openstackPort.id().substring(0, 11); | 256 | String openstackPortName = PORTNAME_PREFIX_VM + openstackPort.id().substring(0, 11); |
253 | Device device = StreamSupport.stream(deviceService.getDevices().spliterator(), false) | 257 | Device device = StreamSupport.stream(deviceService.getDevices().spliterator(), false) |
254 | .filter(d -> findPortinDevice(d, openstackPortName)) | 258 | .filter(d -> findPortinDevice(d, openstackPortName)) |
255 | - .findAny() | 259 | + .iterator() |
256 | - .orElse(null); | 260 | + .next(); |
257 | checkNotNull(device, DEVICENOTNULL); | 261 | checkNotNull(device, DEVICENOTNULL); |
258 | return device; | 262 | return device; |
259 | } | 263 | } |
... | @@ -268,7 +272,7 @@ public class OpenstackRoutingRulePopulator { | ... | @@ -268,7 +272,7 @@ public class OpenstackRoutingRulePopulator { |
268 | } | 272 | } |
269 | 273 | ||
270 | /** | 274 | /** |
271 | - * Builds NiciraExtension for tagging remoteIp of vxlan. | 275 | + * Builds Nicira extension for tagging remoteIp of vxlan. |
272 | * | 276 | * |
273 | * @param id Device Id of vxlan source device | 277 | * @param id Device Id of vxlan source device |
274 | * @param hostIp Remote Ip of vxlan destination device | 278 | * @param hostIp Remote Ip of vxlan destination device |
... | @@ -401,8 +405,8 @@ public class OpenstackRoutingRulePopulator { | ... | @@ -401,8 +405,8 @@ public class OpenstackRoutingRulePopulator { |
401 | StreamSupport.stream(deviceService.getDevices().spliterator(), false) | 405 | StreamSupport.stream(deviceService.getDevices().spliterator(), false) |
402 | .forEach(d -> { | 406 | .forEach(d -> { |
403 | ForwardingObjective.Flag flag = checkGatewayNode(d.id()) ? | 407 | ForwardingObjective.Flag flag = checkGatewayNode(d.id()) ? |
404 | - ForwardingObjective.Flag.VERSATILE : ForwardingObjective.Flag.SPECIFIC; | 408 | + ForwardingObjective.Flag.VERSATILE : |
405 | - | 409 | + ForwardingObjective.Flag.SPECIFIC; |
406 | removeRule(d.id(), sBuilder, flag, ROUTING_RULE_PRIORITY); | 410 | removeRule(d.id(), sBuilder, flag, ROUTING_RULE_PRIORITY); |
407 | }); | 411 | }); |
408 | 412 | ||
... | @@ -514,4 +518,120 @@ public class OpenstackRoutingRulePopulator { | ... | @@ -514,4 +518,120 @@ public class OpenstackRoutingRulePopulator { |
514 | removeRule(getGatewayNode().id(), sIncomingBuilder, ForwardingObjective.Flag.VERSATILE, FLOATING_RULE_PRIORITY); | 518 | removeRule(getGatewayNode().id(), sIncomingBuilder, ForwardingObjective.Flag.VERSATILE, FLOATING_RULE_PRIORITY); |
515 | } | 519 | } |
516 | 520 | ||
521 | + /** | ||
522 | + * Populates L3 rules for east to west traffic. | ||
523 | + * | ||
524 | + * @param p target VM | ||
525 | + * @param targetList target openstackRouterInterfaces | ||
526 | + */ | ||
527 | + public void populateL3Rules(OpenstackPort p, List<OpenstackRouterInterface> targetList) { | ||
528 | + Device device = getDevicefromOpenstackPort(p); | ||
529 | + Port port = getPortFromOpenstackPort(device, p); | ||
530 | + Ip4Address vmIp = (Ip4Address) p.fixedIps().values().iterator().next(); | ||
531 | + | ||
532 | + if (port == null) { | ||
533 | + return; | ||
534 | + } | ||
535 | + | ||
536 | + targetList.forEach(routerInterface -> { | ||
537 | + OpenstackPort openstackPort = openstackService.port(routerInterface.portId()); | ||
538 | + long vni = getVni(openstackPort.networkId()); | ||
539 | + | ||
540 | + if (vmIp == null) { | ||
541 | + return; | ||
542 | + } | ||
543 | + | ||
544 | + populateL3RulestoSameNode(vmIp, p, port, device, vni); | ||
545 | + | ||
546 | + deviceService.getAvailableDevices().forEach(d -> { | ||
547 | + if (!d.equals(device) && !d.equals(getGatewayNode())) { | ||
548 | + populateL3RulestoDifferentNode(vmIp, vni, d.id(), getHostIpfromOpenstackPort(p)); | ||
549 | + } | ||
550 | + }); | ||
551 | + | ||
552 | + }); | ||
553 | + } | ||
554 | + | ||
555 | + private void populateL3RulestoDifferentNode(Ip4Address vmIp, long vni, DeviceId deviceId, Ip4Address hostIp) { | ||
556 | + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); | ||
557 | + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); | ||
558 | + | ||
559 | + sBuilder.matchEthType(Ethernet.TYPE_IPV4) | ||
560 | + .matchTunnelId(vni) | ||
561 | + .matchIPDst(vmIp.toIpPrefix()); | ||
562 | + tBuilder.extension(buildNiciraExtenstion(deviceId, hostIp), deviceId) | ||
563 | + .setOutput(getTunnelPort(deviceId)); | ||
564 | + | ||
565 | + ForwardingObjective fo = DefaultForwardingObjective.builder() | ||
566 | + .withSelector(sBuilder.build()) | ||
567 | + .withTreatment(tBuilder.build()) | ||
568 | + .withPriority(ROUTING_RULE_PRIORITY) | ||
569 | + .withFlag(ForwardingObjective.Flag.SPECIFIC) | ||
570 | + .fromApp(appId) | ||
571 | + .add(); | ||
572 | + | ||
573 | + flowObjectiveService.forward(deviceId, fo); | ||
574 | + } | ||
575 | + | ||
576 | + private void populateL3RulestoSameNode(Ip4Address vmIp, OpenstackPort p, Port port, Device device, long vni) { | ||
577 | + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); | ||
578 | + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); | ||
579 | + | ||
580 | + sBuilder.matchEthType(Ethernet.TYPE_IPV4) | ||
581 | + .matchIPDst(vmIp.toIpPrefix()) | ||
582 | + .matchTunnelId(vni); | ||
583 | + | ||
584 | + tBuilder.setEthDst(p.macAddress()) | ||
585 | + .setOutput(port.number()); | ||
586 | + | ||
587 | + ForwardingObjective fo = DefaultForwardingObjective.builder() | ||
588 | + .withSelector(sBuilder.build()) | ||
589 | + .withTreatment(tBuilder.build()) | ||
590 | + .withPriority(ROUTING_RULE_PRIORITY) | ||
591 | + .withFlag(ForwardingObjective.Flag.SPECIFIC) | ||
592 | + .fromApp(appId) | ||
593 | + .add(); | ||
594 | + | ||
595 | + flowObjectiveService.forward(device.id(), fo); | ||
596 | + } | ||
597 | + | ||
598 | + private Port getPortFromOpenstackPort(Device device, OpenstackPort p) { | ||
599 | + String openstackPortName = PORTNAME_PREFIX_VM + p.id().substring(0, 11); | ||
600 | + return deviceService.getPorts(device.id()) | ||
601 | + .stream() | ||
602 | + .filter(pt -> pt.annotations().value(PORTNAME).equals(openstackPortName)) | ||
603 | + .findAny() | ||
604 | + .orElse(null); | ||
605 | + } | ||
606 | + | ||
607 | + /** | ||
608 | + * Removes L3 rules for routerInterface events. | ||
609 | + * | ||
610 | + * @param vmIp Corresponding Vm ip | ||
611 | + * @param routerInterfaces Corresponding routerInterfaces | ||
612 | + */ | ||
613 | + public void removeL3Rules(Ip4Address vmIp, List<OpenstackRouterInterface> routerInterfaces) { | ||
614 | + if (vmIp == null) { | ||
615 | + return; | ||
616 | + } | ||
617 | + | ||
618 | + OpenstackRoutingService routingService = getService(OpenstackRoutingService.class); | ||
619 | + | ||
620 | + deviceService.getAvailableDevices().forEach(d -> { | ||
621 | + if (!d.equals(getGatewayNode())) { | ||
622 | + routerInterfaces.forEach(routerInterface -> { | ||
623 | + String networkId = routingService.networkIdForRouterInterface(routerInterface.portId()); | ||
624 | + long vni = getVni(networkId); | ||
625 | + | ||
626 | + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); | ||
627 | + | ||
628 | + sBuilder.matchEthType(Ethernet.TYPE_IPV4) | ||
629 | + .matchIPDst(vmIp.toIpPrefix()) | ||
630 | + .matchTunnelId(vni); | ||
631 | + | ||
632 | + removeRule(d.id(), sBuilder, ForwardingObjective.Flag.SPECIFIC, ROUTING_RULE_PRIORITY); | ||
633 | + }); | ||
634 | + } | ||
635 | + }); | ||
636 | + } | ||
517 | } | 637 | } | ... | ... |
-
Please register or login to post a comment