Committed by
Gerrit Code Review
[ONOS-4703,4704] SONA : Floating IP handling in SONA initialization
Generates flow rules for existing Floating IPs when SONA is initialized. Change-Id: I0cb86345600c3cf3ee72fca176ae6d82e7a8cc36
Showing
5 changed files
with
84 additions
and
9 deletions
| ... | @@ -105,6 +105,15 @@ public interface OpenstackInterfaceService { | ... | @@ -105,6 +105,15 @@ public interface OpenstackInterfaceService { |
| 105 | * @param id security group id | 105 | * @param id security group id |
| 106 | * @return security group information | 106 | * @return security group information |
| 107 | */ | 107 | */ |
| 108 | - OpenstackSecurityGroup getSecurityGroup(String id); | 108 | + OpenstackSecurityGroup securityGroup(String id); |
| 109 | + | ||
| 110 | + /** | ||
| 111 | + * Returns collection of OpenStack floating IP information. | ||
| 112 | + * | ||
| 113 | + * @return collection of OpenStack floating IP information | ||
| 114 | + */ | ||
| 115 | + Collection<OpenstackFloatingIP> floatingIps(); | ||
| 116 | + | ||
| 117 | + | ||
| 109 | 118 | ||
| 110 | } | 119 | } | ... | ... |
| ... | @@ -33,6 +33,7 @@ import org.onosproject.net.config.ConfigFactory; | ... | @@ -33,6 +33,7 @@ import org.onosproject.net.config.ConfigFactory; |
| 33 | import org.onosproject.net.config.NetworkConfigEvent; | 33 | import org.onosproject.net.config.NetworkConfigEvent; |
| 34 | import org.onosproject.net.config.NetworkConfigListener; | 34 | import org.onosproject.net.config.NetworkConfigListener; |
| 35 | import org.onosproject.net.config.NetworkConfigRegistry; | 35 | import org.onosproject.net.config.NetworkConfigRegistry; |
| 36 | +import org.onosproject.openstackinterface.OpenstackFloatingIP; | ||
| 36 | import org.onosproject.openstackinterface.OpenstackInterfaceService; | 37 | import org.onosproject.openstackinterface.OpenstackInterfaceService; |
| 37 | import org.onosproject.openstackinterface.OpenstackNetwork; | 38 | import org.onosproject.openstackinterface.OpenstackNetwork; |
| 38 | import org.onosproject.openstackinterface.OpenstackInterfaceConfig; | 39 | import org.onosproject.openstackinterface.OpenstackInterfaceConfig; |
| ... | @@ -40,6 +41,7 @@ import org.onosproject.openstackinterface.OpenstackPort; | ... | @@ -40,6 +41,7 @@ import org.onosproject.openstackinterface.OpenstackPort; |
| 40 | import org.onosproject.openstackinterface.OpenstackRouter; | 41 | import org.onosproject.openstackinterface.OpenstackRouter; |
| 41 | import org.onosproject.openstackinterface.OpenstackSecurityGroup; | 42 | import org.onosproject.openstackinterface.OpenstackSecurityGroup; |
| 42 | import org.onosproject.openstackinterface.OpenstackSubnet; | 43 | import org.onosproject.openstackinterface.OpenstackSubnet; |
| 44 | +import org.onosproject.openstackinterface.web.OpenstackFloatingIpCodec; | ||
| 43 | import org.onosproject.openstackinterface.web.OpenstackNetworkCodec; | 45 | import org.onosproject.openstackinterface.web.OpenstackNetworkCodec; |
| 44 | import org.onosproject.openstackinterface.web.OpenstackPortCodec; | 46 | import org.onosproject.openstackinterface.web.OpenstackPortCodec; |
| 45 | import org.onosproject.openstackinterface.web.OpenstackRouterCodec; | 47 | import org.onosproject.openstackinterface.web.OpenstackRouterCodec; |
| ... | @@ -84,12 +86,14 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { | ... | @@ -84,12 +86,14 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { |
| 84 | private static final String URI_PORTS = "ports"; | 86 | private static final String URI_PORTS = "ports"; |
| 85 | private static final String URI_SUBNETS = "subnets"; | 87 | private static final String URI_SUBNETS = "subnets"; |
| 86 | private static final String URI_SECURITY_GROUPS = "security-groups"; | 88 | private static final String URI_SECURITY_GROUPS = "security-groups"; |
| 89 | + private static final String URI_FLOATINGIPS = "floatingips"; | ||
| 87 | private static final String URI_TOKENS = "tokens"; | 90 | private static final String URI_TOKENS = "tokens"; |
| 88 | 91 | ||
| 89 | private static final String PATH_ROUTERS = "routers"; | 92 | private static final String PATH_ROUTERS = "routers"; |
| 90 | private static final String PATH_NETWORKS = "networks"; | 93 | private static final String PATH_NETWORKS = "networks"; |
| 91 | private static final String PATH_PORTS = "ports"; | 94 | private static final String PATH_PORTS = "ports"; |
| 92 | private static final String PATH_SUBNETS = "subnets"; | 95 | private static final String PATH_SUBNETS = "subnets"; |
| 96 | + private static final String PATH_FLOATINGIPS = "floatingips"; | ||
| 93 | private static final String PATH_ACCESS = "access"; | 97 | private static final String PATH_ACCESS = "access"; |
| 94 | private static final String PATH_TOKEN = "token"; | 98 | private static final String PATH_TOKEN = "token"; |
| 95 | private static final String PATH_ID = "id"; | 99 | private static final String PATH_ID = "id"; |
| ... | @@ -265,7 +269,7 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { | ... | @@ -265,7 +269,7 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { |
| 265 | * @param id Security Group ID | 269 | * @param id Security Group ID |
| 266 | * @return OpenstackSecurityGroup object or null if fails | 270 | * @return OpenstackSecurityGroup object or null if fails |
| 267 | */ | 271 | */ |
| 268 | - public OpenstackSecurityGroup getSecurityGroup(String id) { | 272 | + public OpenstackSecurityGroup securityGroup(String id) { |
| 269 | Invocation.Builder builder = getClientBuilder(neutronUrl + URI_SECURITY_GROUPS + "/" + id); | 273 | Invocation.Builder builder = getClientBuilder(neutronUrl + URI_SECURITY_GROUPS + "/" + id); |
| 270 | String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). | 274 | String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). |
| 271 | header(HEADER_AUTH_TOKEN, getToken()).get(String.class); | 275 | header(HEADER_AUTH_TOKEN, getToken()).get(String.class); |
| ... | @@ -277,7 +281,7 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { | ... | @@ -277,7 +281,7 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { |
| 277 | OpenstackSecurityGroupCodec sgCodec = new OpenstackSecurityGroupCodec(); | 281 | OpenstackSecurityGroupCodec sgCodec = new OpenstackSecurityGroupCodec(); |
| 278 | securityGroup = sgCodec.decode(node, null); | 282 | securityGroup = sgCodec.decode(node, null); |
| 279 | } catch (IOException e) { | 283 | } catch (IOException e) { |
| 280 | - log.warn("getSecurityGroup()", e); | 284 | + log.warn("securityGroup()", e); |
| 281 | } | 285 | } |
| 282 | 286 | ||
| 283 | return securityGroup; | 287 | return securityGroup; |
| ... | @@ -414,6 +418,30 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { | ... | @@ -414,6 +418,30 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService { |
| 414 | .findAny().orElse(null); | 418 | .findAny().orElse(null); |
| 415 | } | 419 | } |
| 416 | 420 | ||
| 421 | + @Override | ||
| 422 | + public Collection<OpenstackFloatingIP> floatingIps() { | ||
| 423 | + Invocation.Builder builder = getClientBuilder(neutronUrl + URI_FLOATINGIPS); | ||
| 424 | + String response = builder.accept(MediaType.APPLICATION_JSON_TYPE). | ||
| 425 | + header(HEADER_AUTH_TOKEN, getToken()).get(String.class); | ||
| 426 | + | ||
| 427 | + log.debug("floatingIps response:" + response); | ||
| 428 | + | ||
| 429 | + ObjectMapper mapper = new ObjectMapper(); | ||
| 430 | + List<OpenstackFloatingIP> openstackFloatingIPs = Lists.newArrayList(); | ||
| 431 | + try { | ||
| 432 | + ObjectNode node = (ObjectNode) mapper.readTree(response); | ||
| 433 | + ArrayNode floatingIpList = (ArrayNode) node.path(PATH_FLOATINGIPS); | ||
| 434 | + OpenstackFloatingIpCodec fipCodec = new OpenstackFloatingIpCodec(); | ||
| 435 | + floatingIpList.forEach(f -> openstackFloatingIPs.add(fipCodec.decode((ObjectNode) f, null))); | ||
| 436 | + } catch (IOException e) { | ||
| 437 | + log.warn("floatingIps()", e); | ||
| 438 | + } | ||
| 439 | + | ||
| 440 | + openstackFloatingIPs.removeAll(Collections.singleton(null)); | ||
| 441 | + | ||
| 442 | + return openstackFloatingIPs; | ||
| 443 | + } | ||
| 444 | + | ||
| 417 | private class InternalConfigListener implements NetworkConfigListener { | 445 | private class InternalConfigListener implements NetworkConfigListener { |
| 418 | 446 | ||
| 419 | public void configureNetwork() { | 447 | public void configureNetwork() { | ... | ... |
| ... | @@ -295,8 +295,16 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -295,8 +295,16 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
| 295 | routerInterfaceMap.put(routerInterface.portId(), openstackService.port(routerInterface.portId()).networkId()); | 295 | routerInterfaceMap.put(routerInterface.portId(), openstackService.port(routerInterface.portId()).networkId()); |
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | + /** | ||
| 299 | + * Set flow rules for traffic between two different subnets when more than one subnets | ||
| 300 | + * connected to a router. | ||
| 301 | + * | ||
| 302 | + * @param openstackRouter OpenstackRouter Info | ||
| 303 | + * @param openstackPort OpenstackPort Info | ||
| 304 | + */ | ||
| 298 | private void setL3Connection(OpenstackRouter openstackRouter, OpenstackPort openstackPort) { | 305 | private void setL3Connection(OpenstackRouter openstackRouter, OpenstackPort openstackPort) { |
| 299 | Collection<OpenstackRouterInterface> interfaceList = getOpenstackRouterInterface(openstackRouter); | 306 | Collection<OpenstackRouterInterface> interfaceList = getOpenstackRouterInterface(openstackRouter); |
| 307 | + | ||
| 300 | if (interfaceList.size() < 2) { | 308 | if (interfaceList.size() < 2) { |
| 301 | return; | 309 | return; |
| 302 | } | 310 | } |
| ... | @@ -309,6 +317,7 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -309,6 +317,7 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
| 309 | && !p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)) | 317 | && !p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)) |
| 310 | .forEach(p -> rulePopulator.populateL3Rules(p, | 318 | .forEach(p -> rulePopulator.populateL3Rules(p, |
| 311 | getL3ConnectionList(p.networkId(), interfaceList))); | 319 | getL3ConnectionList(p.networkId(), interfaceList))); |
| 320 | + | ||
| 312 | }); | 321 | }); |
| 313 | } else { | 322 | } else { |
| 314 | rulePopulator.populateL3Rules(openstackPort, getL3ConnectionList(openstackPort.networkId(), interfaceList)); | 323 | rulePopulator.populateL3Rules(openstackPort, getL3ConnectionList(openstackPort.networkId(), interfaceList)); |
| ... | @@ -397,13 +406,25 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -397,13 +406,25 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
| 397 | } | 406 | } |
| 398 | 407 | ||
| 399 | private void reloadInitL3Rules() { | 408 | private void reloadInitL3Rules() { |
| 409 | + | ||
| 400 | l3EventExecutorService.execute(() -> | 410 | l3EventExecutorService.execute(() -> |
| 401 | openstackService.ports() | 411 | openstackService.ports() |
| 402 | .stream() | 412 | .stream() |
| 403 | - .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)) | 413 | + .forEach(p -> |
| 404 | - .forEach(p -> updateRouterInterface(portToRouterInterface(p))) | 414 | + { |
| 415 | + if (p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)) { | ||
| 416 | + updateRouterInterface(portToRouterInterface(p)); | ||
| 417 | + } else { | ||
| 418 | + Optional<Ip4Address> vmIp = p.fixedIps().values().stream().findAny(); | ||
| 419 | + if (vmIp.isPresent()) { | ||
| 420 | + OpenstackFloatingIP floatingIP = getOpenstackFloatingIp(vmIp.get()); | ||
| 421 | + if (floatingIP != null) { | ||
| 422 | + updateFloatingIP(floatingIP); | ||
| 423 | + } | ||
| 424 | + } | ||
| 425 | + } | ||
| 426 | + }) | ||
| 405 | ); | 427 | ); |
| 406 | - | ||
| 407 | } | 428 | } |
| 408 | 429 | ||
| 409 | private OpenstackRouterInterface portToRouterInterface(OpenstackPort p) { | 430 | private OpenstackRouterInterface portToRouterInterface(OpenstackPort p) { |
| ... | @@ -559,6 +580,19 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -559,6 +580,19 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
| 559 | ip.equals(ip4Address)).count() > 0 ? openstackPort : null; | 580 | ip.equals(ip4Address)).count() > 0 ? openstackPort : null; |
| 560 | } | 581 | } |
| 561 | 582 | ||
| 583 | + private OpenstackFloatingIP getOpenstackFloatingIp(Ip4Address vmIp) { | ||
| 584 | + Optional<OpenstackFloatingIP> floatingIp = floatingIpMap.asJavaMap().values().stream() | ||
| 585 | + .filter(f -> f.portId() != null && f.fixedIpAddress().equals(vmIp)) | ||
| 586 | + .findAny(); | ||
| 587 | + | ||
| 588 | + if (floatingIp.isPresent()) { | ||
| 589 | + return floatingIp.get(); | ||
| 590 | + } | ||
| 591 | + log.debug("There is no floating IP information for VM IP {}", vmIp); | ||
| 592 | + | ||
| 593 | + return null; | ||
| 594 | + } | ||
| 595 | + | ||
| 562 | private void readConfiguration() { | 596 | private void readConfiguration() { |
| 563 | config = configService.getConfig("openstacknetworking", OpenstackNetworkingConfig.class); | 597 | config = configService.getConfig("openstacknetworking", OpenstackNetworkingConfig.class); |
| 564 | if (config == null) { | 598 | if (config == null) { |
| ... | @@ -583,6 +617,10 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -583,6 +617,10 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
| 583 | 617 | ||
| 584 | openstackIcmpHandler.requestPacket(appId); | 618 | openstackIcmpHandler.requestPacket(appId); |
| 585 | openstackArpHandler.requestPacket(appId); | 619 | openstackArpHandler.requestPacket(appId); |
| 620 | + | ||
| 621 | + openstackService.floatingIps().stream() | ||
| 622 | + .forEach(f -> floatingIpMap.put(f.id(), f)); | ||
| 623 | + | ||
| 586 | reloadInitL3Rules(); | 624 | reloadInitL3Rules(); |
| 587 | 625 | ||
| 588 | log.info("OpenstackRouting configured"); | 626 | log.info("OpenstackRouting configured"); | ... | ... |
| ... | @@ -89,7 +89,7 @@ public class OpenstackSecurityGroupRulePopulator { | ... | @@ -89,7 +89,7 @@ public class OpenstackSecurityGroupRulePopulator { |
| 89 | */ | 89 | */ |
| 90 | public void populateSecurityGroupRules(DeviceId id, String sgId, Ip4Address vmIp, | 90 | public void populateSecurityGroupRules(DeviceId id, String sgId, Ip4Address vmIp, |
| 91 | Map<String, OpenstackPortInfo> portInfoMap) { | 91 | Map<String, OpenstackPortInfo> portInfoMap) { |
| 92 | - OpenstackSecurityGroup securityGroup = openstackService.getSecurityGroup(sgId); | 92 | + OpenstackSecurityGroup securityGroup = openstackService.securityGroup(sgId); |
| 93 | if (securityGroup != null) { | 93 | if (securityGroup != null) { |
| 94 | securityGroup.rules().stream().forEach(sgRule -> { | 94 | securityGroup.rules().stream().forEach(sgRule -> { |
| 95 | if (sgRule.remoteGroupId() != null && !sgRule.remoteGroupId().equals("null")) { | 95 | if (sgRule.remoteGroupId() != null && !sgRule.remoteGroupId().equals("null")) { |
| ... | @@ -105,7 +105,7 @@ public class OpenstackSecurityGroupRulePopulator { | ... | @@ -105,7 +105,7 @@ public class OpenstackSecurityGroupRulePopulator { |
| 105 | 105 | ||
| 106 | openstackService.ports().stream().forEach(osPort -> | 106 | openstackService.ports().stream().forEach(osPort -> |
| 107 | osPort.securityGroups().stream().forEach(remoteVmSgId -> { | 107 | osPort.securityGroups().stream().forEach(remoteVmSgId -> { |
| 108 | - OpenstackSecurityGroup remoteVmSg = openstackService.getSecurityGroup(remoteVmSgId); | 108 | + OpenstackSecurityGroup remoteVmSg = openstackService.securityGroup(remoteVmSgId); |
| 109 | remoteVmSg.rules().stream() | 109 | remoteVmSg.rules().stream() |
| 110 | .filter(remoteVmSgRule -> remoteVmSgRule.remoteGroupId().equals(sgId)) | 110 | .filter(remoteVmSgRule -> remoteVmSgRule.remoteGroupId().equals(sgId)) |
| 111 | .forEach(remoteVmSgRule -> { | 111 | .forEach(remoteVmSgRule -> { | ... | ... |
| ... | @@ -374,7 +374,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -374,7 +374,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
| 374 | 374 | ||
| 375 | openstackPort.securityGroups().stream().forEach(sgId -> { | 375 | openstackPort.securityGroups().stream().forEach(sgId -> { |
| 376 | if (!securityGroupMap.containsKey(sgId)) { | 376 | if (!securityGroupMap.containsKey(sgId)) { |
| 377 | - securityGroupMap.put(sgId, openstackService.getSecurityGroup(sgId)); | 377 | + securityGroupMap.put(sgId, openstackService.securityGroup(sgId)); |
| 378 | } | 378 | } |
| 379 | }); | 379 | }); |
| 380 | } | 380 | } | ... | ... |
-
Please register or login to post a comment