sangho
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
...@@ -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 }
......