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 {
* @param id security group id
* @return security group information
*/
OpenstackSecurityGroup getSecurityGroup(String id);
OpenstackSecurityGroup securityGroup(String id);
/**
* Returns collection of OpenStack floating IP information.
*
* @return collection of OpenStack floating IP information
*/
Collection<OpenstackFloatingIP> floatingIps();
}
......
......@@ -33,6 +33,7 @@ import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.openstackinterface.OpenstackFloatingIP;
import org.onosproject.openstackinterface.OpenstackInterfaceService;
import org.onosproject.openstackinterface.OpenstackNetwork;
import org.onosproject.openstackinterface.OpenstackInterfaceConfig;
......@@ -40,6 +41,7 @@ import org.onosproject.openstackinterface.OpenstackPort;
import org.onosproject.openstackinterface.OpenstackRouter;
import org.onosproject.openstackinterface.OpenstackSecurityGroup;
import org.onosproject.openstackinterface.OpenstackSubnet;
import org.onosproject.openstackinterface.web.OpenstackFloatingIpCodec;
import org.onosproject.openstackinterface.web.OpenstackNetworkCodec;
import org.onosproject.openstackinterface.web.OpenstackPortCodec;
import org.onosproject.openstackinterface.web.OpenstackRouterCodec;
......@@ -84,12 +86,14 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
private static final String URI_PORTS = "ports";
private static final String URI_SUBNETS = "subnets";
private static final String URI_SECURITY_GROUPS = "security-groups";
private static final String URI_FLOATINGIPS = "floatingips";
private static final String URI_TOKENS = "tokens";
private static final String PATH_ROUTERS = "routers";
private static final String PATH_NETWORKS = "networks";
private static final String PATH_PORTS = "ports";
private static final String PATH_SUBNETS = "subnets";
private static final String PATH_FLOATINGIPS = "floatingips";
private static final String PATH_ACCESS = "access";
private static final String PATH_TOKEN = "token";
private static final String PATH_ID = "id";
......@@ -265,7 +269,7 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
* @param id Security Group ID
* @return OpenstackSecurityGroup object or null if fails
*/
public OpenstackSecurityGroup getSecurityGroup(String id) {
public OpenstackSecurityGroup securityGroup(String id) {
Invocation.Builder builder = getClientBuilder(neutronUrl + URI_SECURITY_GROUPS + "/" + id);
String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
......@@ -277,7 +281,7 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
OpenstackSecurityGroupCodec sgCodec = new OpenstackSecurityGroupCodec();
securityGroup = sgCodec.decode(node, null);
} catch (IOException e) {
log.warn("getSecurityGroup()", e);
log.warn("securityGroup()", e);
}
return securityGroup;
......@@ -414,6 +418,30 @@ public class OpenstackInterfaceManager implements OpenstackInterfaceService {
.findAny().orElse(null);
}
@Override
public Collection<OpenstackFloatingIP> floatingIps() {
Invocation.Builder builder = getClientBuilder(neutronUrl + URI_FLOATINGIPS);
String response = builder.accept(MediaType.APPLICATION_JSON_TYPE).
header(HEADER_AUTH_TOKEN, getToken()).get(String.class);
log.debug("floatingIps response:" + response);
ObjectMapper mapper = new ObjectMapper();
List<OpenstackFloatingIP> openstackFloatingIPs = Lists.newArrayList();
try {
ObjectNode node = (ObjectNode) mapper.readTree(response);
ArrayNode floatingIpList = (ArrayNode) node.path(PATH_FLOATINGIPS);
OpenstackFloatingIpCodec fipCodec = new OpenstackFloatingIpCodec();
floatingIpList.forEach(f -> openstackFloatingIPs.add(fipCodec.decode((ObjectNode) f, null)));
} catch (IOException e) {
log.warn("floatingIps()", e);
}
openstackFloatingIPs.removeAll(Collections.singleton(null));
return openstackFloatingIPs;
}
private class InternalConfigListener implements NetworkConfigListener {
public void configureNetwork() {
......
......@@ -295,8 +295,16 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
routerInterfaceMap.put(routerInterface.portId(), openstackService.port(routerInterface.portId()).networkId());
}
/**
* Set flow rules for traffic between two different subnets when more than one subnets
* connected to a router.
*
* @param openstackRouter OpenstackRouter Info
* @param openstackPort OpenstackPort Info
*/
private void setL3Connection(OpenstackRouter openstackRouter, OpenstackPort openstackPort) {
Collection<OpenstackRouterInterface> interfaceList = getOpenstackRouterInterface(openstackRouter);
if (interfaceList.size() < 2) {
return;
}
......@@ -308,7 +316,8 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
.filter(p -> p.networkId().equals(interfacePort.networkId())
&& !p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE))
.forEach(p -> rulePopulator.populateL3Rules(p,
getL3ConnectionList(p.networkId(), interfaceList)));
getL3ConnectionList(p.networkId(), interfaceList)));
});
} else {
rulePopulator.populateL3Rules(openstackPort, getL3ConnectionList(openstackPort.networkId(), interfaceList));
......@@ -397,13 +406,25 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
}
private void reloadInitL3Rules() {
l3EventExecutorService.execute(() ->
openstackService.ports()
.stream()
.filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE))
.forEach(p -> updateRouterInterface(portToRouterInterface(p)))
openstackService.ports()
.stream()
.forEach(p ->
{
if (p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)) {
updateRouterInterface(portToRouterInterface(p));
} else {
Optional<Ip4Address> vmIp = p.fixedIps().values().stream().findAny();
if (vmIp.isPresent()) {
OpenstackFloatingIP floatingIP = getOpenstackFloatingIp(vmIp.get());
if (floatingIP != null) {
updateFloatingIP(floatingIP);
}
}
}
})
);
}
private OpenstackRouterInterface portToRouterInterface(OpenstackPort p) {
......@@ -559,6 +580,19 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
ip.equals(ip4Address)).count() > 0 ? openstackPort : null;
}
private OpenstackFloatingIP getOpenstackFloatingIp(Ip4Address vmIp) {
Optional<OpenstackFloatingIP> floatingIp = floatingIpMap.asJavaMap().values().stream()
.filter(f -> f.portId() != null && f.fixedIpAddress().equals(vmIp))
.findAny();
if (floatingIp.isPresent()) {
return floatingIp.get();
}
log.debug("There is no floating IP information for VM IP {}", vmIp);
return null;
}
private void readConfiguration() {
config = configService.getConfig("openstacknetworking", OpenstackNetworkingConfig.class);
if (config == null) {
......@@ -583,6 +617,10 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
openstackIcmpHandler.requestPacket(appId);
openstackArpHandler.requestPacket(appId);
openstackService.floatingIps().stream()
.forEach(f -> floatingIpMap.put(f.id(), f));
reloadInitL3Rules();
log.info("OpenstackRouting configured");
......
......@@ -89,7 +89,7 @@ public class OpenstackSecurityGroupRulePopulator {
*/
public void populateSecurityGroupRules(DeviceId id, String sgId, Ip4Address vmIp,
Map<String, OpenstackPortInfo> portInfoMap) {
OpenstackSecurityGroup securityGroup = openstackService.getSecurityGroup(sgId);
OpenstackSecurityGroup securityGroup = openstackService.securityGroup(sgId);
if (securityGroup != null) {
securityGroup.rules().stream().forEach(sgRule -> {
if (sgRule.remoteGroupId() != null && !sgRule.remoteGroupId().equals("null")) {
......@@ -105,7 +105,7 @@ public class OpenstackSecurityGroupRulePopulator {
openstackService.ports().stream().forEach(osPort ->
osPort.securityGroups().stream().forEach(remoteVmSgId -> {
OpenstackSecurityGroup remoteVmSg = openstackService.getSecurityGroup(remoteVmSgId);
OpenstackSecurityGroup remoteVmSg = openstackService.securityGroup(remoteVmSgId);
remoteVmSg.rules().stream()
.filter(remoteVmSgRule -> remoteVmSgRule.remoteGroupId().equals(sgId))
.forEach(remoteVmSgRule -> {
......
......@@ -374,7 +374,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService {
openstackPort.securityGroups().stream().forEach(sgId -> {
if (!securityGroupMap.containsKey(sgId)) {
securityGroupMap.put(sgId, openstackService.getSecurityGroup(sgId));
securityGroupMap.put(sgId, openstackService.securityGroup(sgId));
}
});
}
......