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