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
87 additions
and
12 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 | } |
... | @@ -308,7 +316,8 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { | ... | @@ -308,7 +316,8 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { |
308 | .filter(p -> p.networkId().equals(interfacePort.networkId()) | 316 | .filter(p -> p.networkId().equals(interfacePort.networkId()) |
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