OpenstackRouting refactoring
- Replace OpenstackPortInfo with HostService
- Replace OpenstackRoutingConfig with OpenstackNodeService
(Remove OpenstackRoutingConfig)
- Rebased with 10330 (existing_vm)
- Added initialization process using OpenstackNodeListener
Change-Id: If2ce8eb86d242a7180c9154e1a0f1668b266bf1c
diff --git a/apps/openstacknetworking/routing/pom.xml b/apps/openstacknetworking/routing/pom.xml
index cc4f7d0..06a6d7e 100644
--- a/apps/openstacknetworking/routing/pom.xml
+++ b/apps/openstacknetworking/routing/pom.xml
@@ -68,6 +68,11 @@
<artifactId>onos-scalablegateway</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-app-openstacknode</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
</project>
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIPHandler.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIPHandler.java
index 073a47f..3d1c013 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIPHandler.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackFloatingIPHandler.java
@@ -15,34 +15,39 @@
*/
package org.onosproject.openstacknetworking.routing;
+import org.onosproject.net.Host;
import org.onosproject.openstackinterface.OpenstackFloatingIP;
-import org.onosproject.openstacknetworking.OpenstackPortInfo;
/**
* Handle FloatingIP Event for Managing Flow Rules In Openstack Nodes.
*/
public class OpenstackFloatingIPHandler implements Runnable {
+ public enum Action {
+ ASSOCIATE,
+ DISSASSOCIATE
+ }
+
private final OpenstackFloatingIP floatingIP;
private final OpenstackRoutingRulePopulator rulePopulator;
- private boolean associate;
- private final OpenstackPortInfo portInfo;
+ private final Host host;
+ private final Action action;
+
OpenstackFloatingIPHandler(OpenstackRoutingRulePopulator rulePopulator,
- OpenstackFloatingIP openstackFloatingIP, boolean associate, OpenstackPortInfo portInfo) {
+ OpenstackFloatingIP openstackFloatingIP, Action action, Host host) {
this.floatingIP = openstackFloatingIP;
this.rulePopulator = rulePopulator;
- this.associate = associate;
- this.portInfo = portInfo;
+ this.action = action;
+ this.host = host;
}
@Override
public void run() {
- if (associate) {
+ if (action == Action.ASSOCIATE) {
rulePopulator.populateFloatingIpRules(floatingIP);
} else {
- rulePopulator.removeFloatingIpRules(floatingIP, portInfo);
+ rulePopulator.removeFloatingIpRules(floatingIP, host);
}
-
}
}
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackIcmpHandler.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackIcmpHandler.java
index 9678598..8b3339b 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackIcmpHandler.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackIcmpHandler.java
@@ -20,9 +20,11 @@
import org.onlab.packet.ICMP;
import org.onlab.packet.IPv4;
import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
@@ -30,16 +32,17 @@
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.HostService;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketService;
+import org.onosproject.openstacknetworking.Constants;
import org.onosproject.openstackinterface.OpenstackInterfaceService;
import org.onosproject.openstackinterface.OpenstackPort;
-import org.onosproject.openstacknetworking.OpenstackNetworkingConfig;
-import org.onosproject.openstacknetworking.OpenstackPortInfo;
-import org.onosproject.openstacknetworking.OpenstackSwitchingService;
+import org.onosproject.openstacknode.OpenstackNode;
+import org.onosproject.openstacknode.OpenstackNodeService;
import org.onosproject.scalablegateway.api.ScalableGatewayService;
import org.slf4j.Logger;
@@ -58,37 +61,39 @@
public class OpenstackIcmpHandler {
protected final Logger log = getLogger(getClass());
- private final PacketService packetService;
- private final DeviceService deviceService;
- private final Map<String, OpenstackPortInfo> icmpInfoMap = Maps.newHashMap();
- private final OpenstackSwitchingService openstackSwitchingService;
- private final OpenstackInterfaceService openstackService;
- private final ScalableGatewayService gatewayService;
- private final OpenstackNetworkingConfig config;
- private static final MacAddress GATEWAY_MAC = MacAddress.valueOf("1f:1f:1f:1f:1f:1f");
+
private static final String NETWORK_ROUTER_INTERFACE = "network:router_interface";
private static final String PORTNAME = "portName";
private static final String NETWORK_ROUTER_GATEWAY = "network:router_gateway";
private static final String NETWORK_FLOATING_IP = "network:floatingip";
- private static final String EXTERNAL_NODE_NULL = "There is no external node about this deviceId []";
+
+ private final PacketService packetService;
+ private final DeviceService deviceService;
+ private final ScalableGatewayService gatewayService;
+ private final HostService hostService;
+ private final Map<String, Host> icmpInfoMap = Maps.newHashMap();
+ private final OpenstackInterfaceService openstackService;
+ private final OpenstackNodeService nodeService;
+
/**
* Default constructor.
*
* @param packetService packet service
* @param deviceService device service
* @param openstackService openstackInterface service
- * @param config openstackRoutingConfig
- * @param openstackSwitchingService openstackSwitching service
- * @param gatewayService scalable gateway service
*/
- OpenstackIcmpHandler(PacketService packetService, DeviceService deviceService,
- OpenstackInterfaceService openstackService, OpenstackNetworkingConfig config,
- OpenstackSwitchingService openstackSwitchingService, ScalableGatewayService gatewayService) {
+ OpenstackIcmpHandler(PacketService packetService,
+ DeviceService deviceService,
+ HostService hostService,
+ OpenstackInterfaceService openstackService,
+ OpenstackNodeService nodeService,
+ ScalableGatewayService gatewayService
+ ) {
this.packetService = packetService;
this.deviceService = deviceService;
+ this.hostService = hostService;
this.openstackService = checkNotNull(openstackService);
- this.config = checkNotNull(config);
- this.openstackSwitchingService = checkNotNull(openstackSwitchingService);
+ this.nodeService = nodeService;
this.gatewayService = gatewayService;
}
@@ -103,13 +108,20 @@
.matchIPProtocol(IPv4.PROTOCOL_ICMP)
.build();
- Map<DeviceId, PortNumber> externalInfoMap = getExternalInfo();
+ // TODO: Return the correct gateway node
+ Optional<OpenstackNode> gwNode = nodeService.nodes().stream()
+ .filter(n -> n.type().equals(OpenstackNodeService.NodeType.GATEWAY))
+ .findFirst();
- externalInfoMap.keySet().forEach(deviceId ->
- packetService.requestPackets(icmpSelector,
- PacketPriority.CONTROL,
- appId,
- Optional.of(deviceId)));
+ if (!gwNode.isPresent()) {
+ log.warn("No Gateway is defined.");
+ return;
+ }
+
+ packetService.requestPackets(icmpSelector,
+ PacketPriority.CONTROL,
+ appId,
+ Optional.of(gwNode.get().intBridge()));
}
/**
@@ -135,11 +147,13 @@
if (icmp.getIcmpType() == ICMP.TYPE_ECHO_REQUEST) {
//TODO: Considers icmp between internal subnets which are belonged to the same router.
- OpenstackPortInfo openstackPortInfo =
- getOpenstackPortInfo(Ip4Address.valueOf(ipPacket.getSourceAddress()), ethernet.getSourceMAC());
+ //OpenstackPortInfo openstackPortInfo =
+ // getOpenstackPortInfo(Ip4Address.valueOf(ipPacket.getSourceAddress()), ethernet.getSourceMAC());
//checkNotNull(openstackPortInfo, "openstackPortInfo can not be null");
+ /* XXX Is this handling ICMP to gateway ?????
if (requestToOpenstackRoutingNetwork(ipPacket.getDestinationAddress())) {
+ Host host =
if (openstackPortInfo == null) {
if (config.gatewayBridgeId().equals(context.inPacket().receivedFrom().deviceId().toString())) {
if (portNumber.equals(getPortForAnnotationPortName(deviceId,
@@ -151,15 +165,23 @@
}
return;
} else {
- processIcmpPacketSentToGateway(ipPacket, icmp, openstackPortInfo);
+ processIcmpPacketSentToGateway(ipPacket, icmp, host);
return;
}
}
+ */
- if (ipPacket.getDestinationAddress() == openstackPortInfo.gatewayIP().toInt()) {
- processIcmpPacketSentToGateway(ipPacket, icmp, openstackPortInfo);
+ Optional<Host> host = hostService.getHostsByMac(ethernet.getSourceMAC()).stream().findFirst();
+ if (!host.isPresent()) {
+ log.warn("No host found for MAC {}", ethernet.getSourceMAC());
+ return;
+ }
+
+ IpAddress gatewayIp = IpAddress.valueOf(host.get().annotations().value(Constants.GATEWAY_IP));
+ if (ipPacket.getDestinationAddress() == gatewayIp.getIp4Address().toInt()) {
+ processIcmpPacketSentToGateway(ipPacket, icmp, host.get());
} else {
- Ip4Address pNatIpAddress = pNatIpForPort(openstackPortInfo);
+ Ip4Address pNatIpAddress = pNatIpForPort(host.get());
checkNotNull(pNatIpAddress, "pNatIpAddress can not be null");
sendRequestPacketToExt(ipPacket, icmp, deviceId, pNatIpAddress);
@@ -167,7 +189,7 @@
String icmpInfoKey = String.valueOf(icmpId)
.concat(String.valueOf(pNatIpAddress.toInt()))
.concat(String.valueOf(ipPacket.getDestinationAddress()));
- icmpInfoMap.putIfAbsent(icmpInfoKey, openstackPortInfo);
+ icmpInfoMap.putIfAbsent(icmpInfoKey, host.get());
}
} else if (icmp.getIcmpType() == ICMP.TYPE_ECHO_REPLY) {
String icmpInfoKey = String.valueOf(icmpId)
@@ -190,7 +212,8 @@
icmpRequestIpv4.setPayload(icmpRequest);
Ethernet icmpResponseEth = new Ethernet();
icmpResponseEth.setEtherType(Ethernet.TYPE_IPV4)
- .setSourceMACAddress(config.gatewayExternalInterfaceMac())
+ // TODO: Get the correct GW MAC
+ .setSourceMACAddress(Constants.GW_EXT_INT_MAC)
.setDestinationMACAddress(destMac).setPayload(icmpRequestIpv4);
TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(portNumber).build();
OutboundPacket packet = new DefaultOutboundPacket(deviceId,
@@ -199,13 +222,14 @@
}
private void processIcmpPacketSentToGateway(IPv4 icmpRequestIpv4, ICMP icmpRequest,
- OpenstackPortInfo openstackPortInfo) {
+ Host host) {
icmpRequest.setChecksum((short) 0);
icmpRequest.setIcmpType(ICMP.TYPE_ECHO_REPLY)
.resetChecksum();
+ Ip4Address ipAddress = host.ipAddresses().stream().findAny().get().getIp4Address();
icmpRequestIpv4.setSourceAddress(icmpRequestIpv4.getDestinationAddress())
- .setDestinationAddress(openstackPortInfo.ip().toInt())
+ .setDestinationAddress(ipAddress.toInt())
.resetChecksum();
icmpRequestIpv4.setPayload(icmpRequest);
@@ -213,11 +237,11 @@
Ethernet icmpResponseEth = new Ethernet();
icmpResponseEth.setEtherType(Ethernet.TYPE_IPV4)
- .setSourceMACAddress(GATEWAY_MAC)
- .setDestinationMACAddress(openstackPortInfo.mac())
+ .setSourceMACAddress(Constants.GATEWAY_MAC)
+ .setDestinationMACAddress(host.mac())
.setPayload(icmpRequestIpv4);
- sendResponsePacketToHost(icmpResponseEth, openstackPortInfo);
+ sendResponsePacketToHost(icmpResponseEth, host);
}
private void sendRequestPacketToExt(IPv4 icmpRequestIpv4, ICMP icmpRequest, DeviceId deviceId,
@@ -230,19 +254,27 @@
Ethernet icmpRequestEth = new Ethernet();
icmpRequestEth.setEtherType(Ethernet.TYPE_IPV4)
+ // TODO: Get the correct one - Scalable Gateway ...
+ .setSourceMACAddress(Constants.GW_EXT_INT_MAC)
+ .setDestinationMACAddress(Constants.PHY_ROUTER_MAC)
.setPayload(icmpRequestIpv4);
- TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+ // TODO: Return the correct gateway node
+ Optional<OpenstackNode> gwNode = nodeService.nodes().stream()
+ .filter(n -> n.type().equals(OpenstackNodeService.NodeType.GATEWAY))
+ .findFirst();
- Map<DeviceId, PortNumber> externalInforMap = getExternalInfo();
-
- if (externalInforMap.size() == 0 || !externalInforMap.containsKey(deviceId)) {
- log.error(EXTERNAL_NODE_NULL, deviceId.toString());
+ if (!gwNode.isPresent()) {
+ log.warn("No Gateway is defined.");
return;
}
- tBuilder.setOutput(externalInforMap.get(deviceId));
- TrafficTreatment treatment = tBuilder.build();
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ // FIXME: please double check this.
+ .setOutput(getPortForAnnotationPortName(gwNode.get().intBridge(),
+ // FIXME: please double check this.
+ org.onosproject.openstacknode.Constants.PATCH_INTG_BRIDGE))
+ .build();
OutboundPacket packet = new DefaultOutboundPacket(deviceId,
treatment, ByteBuffer.wrap(icmpRequestEth.serialize()));
@@ -251,59 +283,45 @@
}
private void processResponsePacketFromExternalToHost(IPv4 icmpResponseIpv4, ICMP icmpResponse,
- OpenstackPortInfo openstackPortInfo) {
+ Host host) {
icmpResponse.resetChecksum();
- icmpResponseIpv4.setDestinationAddress(openstackPortInfo.ip().toInt())
+ Ip4Address ipAddress = host.ipAddresses().stream().findFirst().get().getIp4Address();
+ icmpResponseIpv4.setDestinationAddress(ipAddress.toInt())
.resetChecksum();
icmpResponseIpv4.setPayload(icmpResponse);
Ethernet icmpResponseEth = new Ethernet();
icmpResponseEth.setEtherType(Ethernet.TYPE_IPV4)
- .setSourceMACAddress(GATEWAY_MAC)
- .setDestinationMACAddress(openstackPortInfo.mac())
+ .setSourceMACAddress(Constants.GATEWAY_MAC)
+ .setDestinationMACAddress(host.mac())
.setPayload(icmpResponseIpv4);
- sendResponsePacketToHost(icmpResponseEth, openstackPortInfo);
+ sendResponsePacketToHost(icmpResponseEth, host);
}
- private void sendResponsePacketToHost(Ethernet icmpResponseEth, OpenstackPortInfo openstackPortInfo) {
- Map.Entry<String, OpenstackPortInfo> entry = openstackSwitchingService.openstackPortInfo().entrySet().stream()
- .filter(e -> e.getValue().mac().equals(openstackPortInfo.mac()))
- .findAny().orElse(null);
-
- if (entry == null) {
- return;
- }
+ private void sendResponsePacketToHost(Ethernet icmpResponseEth, Host host) {
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setOutput(getPortForAnnotationPortName(openstackPortInfo.deviceId(), entry.getKey()))
+ .setOutput(host.location().port())
.build();
- OutboundPacket packet = new DefaultOutboundPacket(openstackPortInfo.deviceId(),
+ OutboundPacket packet = new DefaultOutboundPacket(host.location().deviceId(),
treatment, ByteBuffer.wrap(icmpResponseEth.serialize()));
packetService.emit(packet);
}
- private OpenstackPortInfo getOpenstackPortInfo(Ip4Address sourceIp, MacAddress sourceMac) {
- checkNotNull(openstackSwitchingService.openstackPortInfo(), "openstackportinfo collection can not be null");
-
- return openstackSwitchingService.openstackPortInfo().values()
- .stream().filter(p -> p.ip().equals(sourceIp) && p.mac().equals(sourceMac))
- .findAny().orElse(null);
- }
-
private short getIcmpId(ICMP icmp) {
return ByteBuffer.wrap(icmp.serialize(), 4, 2).getShort();
}
- private Ip4Address pNatIpForPort(OpenstackPortInfo openstackPortInfo) {
+ private Ip4Address pNatIpForPort(Host host) {
OpenstackPort openstackPort = openstackService.ports().stream()
.filter(p -> p.deviceOwner().equals(NETWORK_ROUTER_INTERFACE) &&
- p.networkId().equals(openstackPortInfo.networkId()))
+ p.networkId().equals(host.annotations().value(Constants.NETWORK_ID)))
.findAny().orElse(null);
checkNotNull(openstackPort, "openstackPort can not be null");
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackPnatHandler.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackPnatHandler.java
index 3f11e6c..ce33e9e 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackPnatHandler.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackPnatHandler.java
@@ -32,7 +32,6 @@
import org.onosproject.openstackinterface.OpenstackInterfaceService;
import org.onosproject.openstackinterface.OpenstackPort;
import org.onosproject.openstackinterface.OpenstackRouter;
-import org.onosproject.openstacknetworking.OpenstackNetworkingConfig;
import org.onosproject.scalablegateway.api.GatewayNode;
import org.onosproject.scalablegateway.api.ScalableGatewayService;
import org.slf4j.Logger;
@@ -52,25 +51,21 @@
volatile PacketContext context;
private final Logger log = LoggerFactory.getLogger(getClass());
- protected PacketService packetService;
-
private final OpenstackRoutingRulePopulator rulePopulator;
private final int portNum;
private final OpenstackPort openstackPort;
private final Port port;
- private OpenstackNetworkingConfig config;
private static final String DEVICE_OWNER_ROUTER_INTERFACE = "network:router_interface";
private static final String EXTERNAL_PORT_NULL = "There is no external port in this deviceId []";
OpenstackPnatHandler(OpenstackRoutingRulePopulator rulePopulator, PacketContext context,
- int portNum, OpenstackPort openstackPort, Port port, OpenstackNetworkingConfig config) {
+ int portNum, OpenstackPort openstackPort, Port port) {
this.rulePopulator = checkNotNull(rulePopulator);
this.context = checkNotNull(context);
this.portNum = checkNotNull(portNum);
this.openstackPort = checkNotNull(openstackPort);
this.port = checkNotNull(port);
- this.config = checkNotNull(config);
}
@Override
@@ -149,6 +144,7 @@
iPacket.resetChecksum();
iPacket.setParent(ethernet);
ethernet.setPayload(iPacket);
+
ScalableGatewayService gatewayService = getService(ScalableGatewayService.class);
GatewayNode gatewayNode = gatewayService.getGatewayNode(deviceId);
if (gatewayNode.getGatewayExternalInterfaceNames().size() == 0) {
@@ -159,7 +155,6 @@
ethernet.resetChecksum();
-
packetService.emit(new DefaultOutboundPacket(deviceId, treatment.build(),
ByteBuffer.wrap(ethernet.serialize())));
}
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingArpHandler.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingArpHandler.java
index 9e23b5d..2c9a304 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingArpHandler.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingArpHandler.java
@@ -34,8 +34,9 @@
import org.onosproject.net.packet.PacketService;
import org.onosproject.openstackinterface.OpenstackInterfaceService;
import org.onosproject.openstackinterface.OpenstackPort;
-import org.onosproject.openstacknetworking.OpenstackNetworkingConfig;
import org.onosproject.scalablegateway.api.ScalableGatewayService;
+import org.onosproject.openstacknetworking.Constants;
+import org.onosproject.openstacknode.OpenstackNodeService;
import org.slf4j.Logger;
import java.nio.ByteBuffer;
@@ -53,23 +54,24 @@
private final PacketService packetService;
private final OpenstackInterfaceService openstackService;
- private final OpenstackNetworkingConfig config;
private final ScalableGatewayService gatewayService;
+ private final OpenstackNodeService nodeService;
private static final String NETWORK_ROUTER_GATEWAY = "network:router_gateway";
private static final String NETWORK_FLOATING_IP = "network:floatingip";
/**
* Default constructor.
- * @param packetService packet service
+ *
+ * @param packetService packet service
* @param openstackService openstackInterface service
- * @param config openstackRoutingConfig
- * @param gatewayService
+ * @param gatewayService gateway service
+ * @param nodeService openstackNodeService
*/
OpenstackRoutingArpHandler(PacketService packetService, OpenstackInterfaceService openstackService,
- OpenstackNetworkingConfig config, ScalableGatewayService gatewayService) {
+ OpenstackNodeService nodeService, ScalableGatewayService gatewayService) {
this.packetService = packetService;
this.openstackService = checkNotNull(openstackService);
- this.config = checkNotNull(config);
+ this.nodeService = nodeService;
this.gatewayService = gatewayService;
}
@@ -118,7 +120,8 @@
if (getTargetMacForTargetIp(targetIp.getIp4Address()) == MacAddress.NONE) {
return;
}
- MacAddress targetMac = MacAddress.valueOf(config.gatewayExternalInterfaceMac());
+ // FIXME: Set the correct gateway
+ MacAddress targetMac = Constants.GW_EXT_INT_MAC;
Ethernet ethReply = ARP.buildArpReply(targetIp.getIp4Address(),
targetMac, ethernet);
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java
index 6da1523..1e0b9fd 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java
@@ -16,6 +16,7 @@
package org.onosproject.openstacknetworking.routing;
import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -25,38 +26,47 @@
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.UDP;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
import org.onosproject.net.Port;
-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.net.config.NetworkConfigService;
-import org.onosproject.net.device.DeviceEvent;
-import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.DriverService;
import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderRegistry;
+import org.onosproject.net.host.HostProviderService;
+import org.onosproject.net.host.HostService;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
import org.onosproject.openstackinterface.OpenstackFloatingIP;
import org.onosproject.openstackinterface.OpenstackInterfaceService;
import org.onosproject.openstackinterface.OpenstackPort;
import org.onosproject.openstackinterface.OpenstackRouter;
import org.onosproject.openstackinterface.OpenstackRouterInterface;
-import org.onosproject.openstacknetworking.OpenstackNetworkingConfig;
-import org.onosproject.openstacknetworking.OpenstackPortInfo;
import org.onosproject.openstacknetworking.OpenstackRoutingService;
-import org.onosproject.openstacknetworking.OpenstackSubjectFactories;
-import org.onosproject.openstacknetworking.OpenstackSwitchingService;
import org.onosproject.scalablegateway.api.ScalableGatewayService;
+import org.onosproject.openstacknetworking.routing.OpenstackFloatingIPHandler.Action;
+import org.onosproject.openstacknetworking.Constants;
+import org.onosproject.openstacknode.OpenstackNode;
+import org.onosproject.openstacknode.OpenstackNodeEvent;
+import org.onosproject.openstacknode.OpenstackNodeListener;
+import org.onosproject.openstacknode.OpenstackNodeService;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.Serializer;
@@ -66,8 +76,8 @@
import java.util.Collection;
import java.util.List;
-import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
@@ -97,31 +107,35 @@
protected OpenstackInterfaceService openstackService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected OpenstackSwitchingService openstackSwitchingService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowObjectiveService flowObjectiveService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DriverService driverService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected NetworkConfigService configService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected NetworkConfigRegistry configRegistry;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected HostService hostService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected HostProviderRegistry hostProviderRegistry;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ScalableGatewayService gatewayService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected OpenstackNodeService nodeService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MastershipService mastershipService;
+
private ApplicationId appId;
private ConsistentMap<Integer, String> tpPortNumMap; // Map<PortNum, allocated VM`s Mac & destionation Ip address>
private ConsistentMap<String, OpenstackFloatingIP> floatingIpMap; // Map<FloatingIp`s Id, FloatingIp object>
// Map<RouterInterface`s portId, Corresponded port`s network id>
private ConsistentMap<String, String> routerInterfaceMap;
+ private static final ProviderId PID = new ProviderId("of", "org.onosproject.openstackroutering", true);
private static final String APP_ID = "org.onosproject.openstackrouting";
private static final String PORT_NAME = "portName";
private static final String PORTNAME_PREFIX_VM = "tap";
@@ -134,18 +148,6 @@
private static final int TP_PORT_MINIMUM_NUM = 1024;
private static final int TP_PORT_MAXIMUM_NUM = 65535;
- private final ConfigFactory configFactory =
- new ConfigFactory(OpenstackSubjectFactories.USER_DEFINED_SUBJECT_FACTORY, OpenstackNetworkingConfig.class,
- "config") {
- @Override
- public OpenstackNetworkingConfig createConfig() {
- return new OpenstackNetworkingConfig();
- }
- };
-
- private final NetworkConfigListener configListener = new InternalConfigListener();
-
- private OpenstackNetworkingConfig config;
private static final KryoNamespace.Builder FLOATING_IP_SERIALIZER = KryoNamespace.newBuilder()
.register(KryoNamespaces.API)
.register(OpenstackFloatingIP.FloatingIpStatus.class)
@@ -158,7 +160,8 @@
.register(KryoNamespaces.API);
private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor();
- private InternalDeviceListener internalDeviceListener = new InternalDeviceListener();
+ private InternalHostListener internalHostListener = new InternalHostListener();
+ private InternalOpenstackNodeListener internalNodeListener = new InternalOpenstackNodeListener();
private ExecutorService l3EventExecutorService =
Executors.newSingleThreadExecutor(groupedThreads("onos/openstackrouting", "L3-event"));
private ExecutorService icmpEventExecutorService =
@@ -168,15 +171,16 @@
private OpenstackIcmpHandler openstackIcmpHandler;
private OpenstackRoutingArpHandler openstackArpHandler;
private OpenstackRoutingRulePopulator rulePopulator;
- private Map<DeviceId, Ip4Address> computeNodeMap;
+
+ private HostProviderService hostProviderService;
+ private final HostProvider hostProvider = new InternalHostProvider();
@Activate
protected void activate() {
appId = coreService.registerApplication(APP_ID);
- packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1));
- configRegistry.registerConfigFactory(configFactory);
- configService.addListener(configListener);
- deviceService.addListener(internalDeviceListener);
+ hostService.addListener(internalHostListener);
+ nodeService.addListener(internalNodeListener);
+ hostProviderService = hostProviderRegistry.register(hostProvider);
floatingIpMap = storageService.<String, OpenstackFloatingIP>consistentMapBuilder()
.withSerializer(Serializer.using(FLOATING_IP_SERIALIZER.build()))
@@ -194,15 +198,15 @@
.withApplicationId(appId)
.build();
- readConfiguration();
-
log.info("started");
}
@Deactivate
protected void deactivate() {
packetService.removeProcessor(internalPacketProcessor);
- deviceService.removeListener(internalDeviceListener);
+ hostService.removeListener(internalHostListener);
+ nodeService.removeListener(internalNodeListener);
+
l3EventExecutorService.shutdown();
icmpEventExecutorService.shutdown();
arpEventExecutorService.shutdown();
@@ -228,20 +232,27 @@
}
if (openstackFloatingIp.portId() == null || openstackFloatingIp.portId().equals("null")) {
OpenstackFloatingIP floatingIp = floatingIpMap.get(openstackFloatingIp.id()).value();
- OpenstackPortInfo portInfo = openstackSwitchingService.openstackPortInfo()
- .get(PORTNAME_PREFIX_VM.concat(floatingIp.portId().substring(0, 11)));
- if (portInfo == null) {
- log.warn("There`s no portInfo information about portId {}", floatingIp.portId());
+ // XXX When the VM has been removed, host information has been removed or not ???
+ Optional<Host> host = hostService.getHostsByIp(openstackFloatingIp.fixedIpAddress().getIp4Address())
+ .stream()
+ .findFirst();
+ if (!host.isPresent()) {
+ log.warn("No Host info with the VM IP the Floating IP address {} is found",
+ openstackFloatingIp.floatingIpAddress());
return;
}
l3EventExecutorService.execute(
- new OpenstackFloatingIPHandler(rulePopulator, floatingIp, false, portInfo));
+ new OpenstackFloatingIPHandler(rulePopulator, floatingIp, Action.DISSASSOCIATE, host.get()));
floatingIpMap.replace(floatingIp.id(), openstackFloatingIp);
+ registerFloatingIpToHostService(openstackFloatingIp, Action.DISSASSOCIATE);
} else {
floatingIpMap.put(openstackFloatingIp.id(), openstackFloatingIp);
l3EventExecutorService.execute(
- new OpenstackFloatingIPHandler(rulePopulator, openstackFloatingIp, true, null));
+ new OpenstackFloatingIPHandler(rulePopulator, openstackFloatingIp, Action.ASSOCIATE, null));
+ registerFloatingIpToHostService(openstackFloatingIp, Action.ASSOCIATE);
}
+
+
}
@Override
@@ -356,6 +367,10 @@
private void removeL3RulesForRouterInterface(OpenstackRouterInterface routerInterface, OpenstackRouter router,
List<OpenstackRouterInterface> newList) {
+ if (!routerInterfaceMap.containsKey(routerInterface.portId())) {
+ log.warn("No router interface information found for {}", routerInterface.portId());
+ return;
+ }
openstackService.ports(routerInterfaceMap.get(routerInterface.portId()).value()).forEach(p -> {
Ip4Address vmIp = (Ip4Address) p.fixedIps().values().toArray()[0];
if (newList == null) {
@@ -368,6 +383,7 @@
);
}
+ /*
@Override
public void checkDisassociatedFloatingIp(String portId, OpenstackPortInfo portInfo) {
if (floatingIpMap.size() < 1) {
@@ -393,6 +409,7 @@
log.warn("portInfo is null as timing issue between ovs port update event and openstack deletePort event");
}
}
+ */
@Override
public String networkIdForRouterInterface(String portId) {
@@ -445,6 +462,11 @@
@Override
public void process(PacketContext context) {
+ DeviceId senderDeviceId = context.inPacket().receivedFrom().deviceId();
+ if (!nodeService.routerBridge(senderDeviceId).isPresent()) {
+ log.warn("No router bridge for {} is found.", senderDeviceId);
+ return;
+ }
if (context.isHandled()) {
return;
} else if (!checkGatewayNode(context.inPacket().receivedFrom().deviceId())) {
@@ -482,7 +504,8 @@
OpenstackPort openstackPort = getOpenstackPort(ethernet.getSourceMAC(),
Ip4Address.valueOf(iPacket.getSourceAddress()));
l3EventExecutorService.execute(new OpenstackPnatHandler(rulePopulator, context,
- portNum, openstackPort, port, config));
+ portNum, openstackPort, port));
+
} else {
log.warn("There`s no external interface");
}
@@ -602,75 +625,166 @@
return null;
}
- private void readConfiguration() {
- config = configService.getConfig("openstacknetworking", OpenstackNetworkingConfig.class);
- if (config == null) {
- log.error("No configuration found");
+ private Optional<OpenstackPort> getRouterInterfacePort(String networkId) {
+
+ return openstackService.ports()
+ .stream()
+ .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)
+ && p.networkId().equals(networkId))
+ .findAny();
+ }
+
+ // TODO: Remove the function and the related codes when vRouter is running on different ONOS instance.
+ private void registerFloatingIpToHostService(OpenstackFloatingIP openstackFloatingIp, Action action) {
+
+ Optional<Host> hostOptional = hostService.getHostsByIp(openstackFloatingIp.fixedIpAddress())
+ .stream()
+ .findFirst();
+ if (!hostOptional.isPresent()) {
+ log.warn("No host with IP {} is registered and cannot add the floating IP. ",
+ openstackFloatingIp.floatingIpAddress());
return;
}
- rulePopulator = new OpenstackRoutingRulePopulator(appId, openstackService, flowObjectiveService,
- deviceService, driverService, config, gatewayService);
- openstackIcmpHandler = new OpenstackIcmpHandler(packetService, deviceService,
- openstackService, config, openstackSwitchingService, gatewayService);
- openstackArpHandler = new OpenstackRoutingArpHandler(packetService, openstackService,
- config, gatewayService);
- openstackIcmpHandler.requestPacket(appId);
- openstackArpHandler.requestPacket(appId);
+ Host host = hostOptional.get();
+ Set<IpAddress> ipAddresses = Sets.newHashSet();
+ if (action == Action.ASSOCIATE) {
+ ipAddresses.add(openstackFloatingIp.floatingIpAddress());
+ }
- openstackService.floatingIps().stream()
- .forEach(f -> floatingIpMap.put(f.id(), f));
+ HostDescription hostDescription =
+ new DefaultHostDescription(host.mac(), host.vlan(), host.location(), ipAddresses,
+ (DefaultAnnotations) host.annotations());
- reloadInitL3Rules();
-
- log.info("OpenstackRouting configured");
+ hostProviderService.hostDetected(host.id(), hostDescription, false);
}
- private class InternalConfigListener implements NetworkConfigListener {
+ private class InternalHostListener implements HostListener {
- @Override
- public void event(NetworkConfigEvent event) {
- if (!event.configClass().equals(OpenstackNetworkingConfig.class)) {
+ private void hostDetected(Host host) {
+
+ String portId = host.annotations().value(Constants.PORT_ID);
+ OpenstackPort openstackPort = openstackService.port(portId);
+ if (openstackPort == null) {
+ log.warn("No OpenstackPort information found from OpenStack for port ID {}", portId);
return;
}
- if (event.type().equals(NetworkConfigEvent.Type.CONFIG_ADDED) ||
- event.type().equals(NetworkConfigEvent.Type.CONFIG_UPDATED)) {
- l3EventExecutorService.execute(OpenstackRoutingManager.this::readConfiguration);
+ Optional<OpenstackPort> routerPort = getRouterInterfacePort(openstackPort.networkId());
+ if (routerPort.isPresent()) {
+ OpenstackRouterInterface routerInterface = portToRouterInterface(routerPort.get());
+ l3EventExecutorService.execute(() ->
+ setL3Connection(getOpenstackRouter(routerInterface.id()), openstackPort));
+
+ }
+ }
+
+ private void hostRemoved(Host host) {
+ String portId = host.annotations().value(Constants.PORT_ID);
+ OpenstackPort openstackPort = openstackService.port(portId);
+ if (openstackPort == null) {
+ log.warn("No OpenstackPort information found from OpenStack for port ID {}", portId);
+ return;
+ }
+
+ Optional<OpenstackPort> routerPort = getRouterInterfacePort(openstackPort.networkId());
+ if (routerPort.isPresent()) {
+ OpenstackRouterInterface routerInterface = portToRouterInterface(routerPort.get());
+ IpAddress ipAddress = host.ipAddresses().stream().findFirst().get();
+ l3EventExecutorService.execute(() -> rulePopulator.removeL3Rules(ipAddress.getIp4Address(),
+ getL3ConnectionList(host.annotations().value(Constants.NETWORK_ID),
+ getOpenstackRouterInterface(getOpenstackRouter(routerInterface.id())))));
+ }
+ }
+
+ private boolean isValidHost(Host host) {
+ return !host.ipAddresses().isEmpty() &&
+ host.annotations().value(Constants.VXLAN_ID) != null &&
+ host.annotations().value(Constants.NETWORK_ID) != null &&
+ host.annotations().value(Constants.TENANT_ID) != null &&
+ host.annotations().value(Constants.PORT_ID) != null;
+ }
+
+ @Override
+ public void event(HostEvent event) {
+ Host host = event.subject();
+ if (!mastershipService.isLocalMaster(host.location().deviceId())) {
+ // do not allow to proceed without mastership
+ return;
+ }
+
+ if (!isValidHost(host)) {
+ log.debug("Invalid host event, ignore it {}", host);
+ return;
+ }
+
+ switch (event.type()) {
+ case HOST_UPDATED:
+ case HOST_ADDED:
+ l3EventExecutorService.execute(() -> hostDetected(host));
+ break;
+ case HOST_REMOVED:
+ l3EventExecutorService.execute(() -> hostRemoved(host));
+ break;
+ default:
+ break;
}
}
}
- private class InternalDeviceListener implements DeviceListener {
+ private class InternalOpenstackNodeListener implements OpenstackNodeListener {
+
+ private void nodeComplete() {
+
+ rulePopulator = new OpenstackRoutingRulePopulator(appId, openstackService, flowObjectiveService,
+ deviceService, driverService, nodeService, gatewayService);
+ openstackIcmpHandler = new OpenstackIcmpHandler(packetService, deviceService, hostService,
+ openstackService, nodeService, gatewayService);
+ openstackArpHandler = new OpenstackRoutingArpHandler(packetService, openstackService, nodeService,
+ gatewayService);
+
+ // Packet handlers must be started AFTER all initialization processes.
+ packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1));
+
+ openstackIcmpHandler.requestPacket(appId);
+ openstackArpHandler.requestPacket(appId);
+
+ openstackService.floatingIps().stream()
+ .forEach(f -> floatingIpMap.put(f.id(), f));
+
+ reloadInitL3Rules();
+ }
@Override
- public void event(DeviceEvent deviceEvent) {
- if (deviceEvent.type() == DeviceEvent.Type.PORT_UPDATED) {
- Port port = deviceEvent.port();
- OpenstackPortInfo portInfo = openstackSwitchingService.openstackPortInfo()
- .get(port.annotations().value(PORT_NAME));
- OpenstackPort openstackPort = openstackService.port(port);
- OpenstackPort interfacePort = openstackService.ports()
- .stream()
- .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)
- && p.networkId().equals(openstackPort.networkId()))
- .findAny()
- .orElse(null);
- if (portInfo == null && openstackPort == null) {
- log.warn("As delete event timing issue between routing and switching, Can`t delete L3 rules");
- return;
- }
- if ((port.isEnabled()) && (interfacePort != null)) {
- OpenstackRouterInterface routerInterface = portToRouterInterface(interfacePort);
- l3EventExecutorService.execute(() ->
- setL3Connection(getOpenstackRouter(routerInterface.id()), openstackPort));
- } else if (interfacePort != null) {
- OpenstackRouterInterface routerInterface = portToRouterInterface(interfacePort);
- l3EventExecutorService.execute(() -> rulePopulator.removeL3Rules(portInfo.ip(),
- getL3ConnectionList(portInfo.networkId(),
- getOpenstackRouterInterface(getOpenstackRouter(routerInterface.id())))));
- }
+ public void event(OpenstackNodeEvent event) {
+ OpenstackNode node = event.node();
+
+ switch (event.type()) {
+ case COMPLETE:
+ log.info("COMPLETE node {} detected", node.hostname());
+ l3EventExecutorService.execute(() -> nodeComplete());
+ break;
+ case INCOMPLETE:
+ break;
+ default:
+ break;
}
+
+ }
+ }
+
+ private class InternalHostProvider extends AbstractProvider implements HostProvider {
+
+ /**
+ * Creates a provider with the supplier identifier.
+ */
+ protected InternalHostProvider() {
+ super(PID);
+ }
+
+ @Override
+ public void triggerProbe(Host host) {
+ // nothing to do
}
}
diff --git a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingRulePopulator.java b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingRulePopulator.java
index 57444d0..e448241 100644
--- a/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingRulePopulator.java
+++ b/apps/openstacknetworking/routing/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingRulePopulator.java
@@ -29,6 +29,7 @@
import org.onosproject.core.GroupId;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
@@ -54,14 +55,16 @@
import org.onosproject.openstackinterface.OpenstackRouterInterface;
import org.onosproject.openstackinterface.OpenstackSubnet;
import org.onosproject.openstackinterface.OpenstackFloatingIP;
-import org.onosproject.openstacknetworking.OpenstackNetworkingConfig;
-import org.onosproject.openstacknetworking.OpenstackPortInfo;
+import org.onosproject.openstacknetworking.Constants;
import org.onosproject.openstacknetworking.OpenstackRoutingService;
import org.onosproject.scalablegateway.api.ScalableGatewayService;
+import org.onosproject.openstacknode.OpenstackNode;
+import org.onosproject.openstacknode.OpenstackNodeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
+import java.util.Optional;
import java.util.stream.StreamSupport;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -79,8 +82,8 @@
private final OpenstackInterfaceService openstackService;
private final DeviceService deviceService;
private final DriverService driverService;
- private final OpenstackNetworkingConfig config;
private final ScalableGatewayService gatewayService;
+ private final OpenstackNodeService nodeService;
private static final String PORTNAME_PREFIX_TUNNEL = "vxlan";
private static final String PORTNAME = "portName";
@@ -95,7 +98,6 @@
private static final int PNAT_RULE_PRIORITY = 26000;
private static final int PNAT_TIMEOUT = 120;
private static final int PREFIX_LENGTH = 32;
- private static final MacAddress GATEWAYMAC = MacAddress.valueOf("1f:1f:1f:1f:1f:1f");
private InboundPacket inboundPacket;
private OpenstackPort openstackPort;
@@ -111,20 +113,22 @@
* @param flowObjectiveService FlowObjectiveService
* @param deviceService DeviceService
* @param driverService DriverService
- * @param config Configuration for openstack environment
* @param gatewayService scalable gateway service
*/
- public OpenstackRoutingRulePopulator(ApplicationId appId, OpenstackInterfaceService openstackService,
- FlowObjectiveService flowObjectiveService, DeviceService deviceService,
- DriverService driverService, OpenstackNetworkingConfig config,
+ public OpenstackRoutingRulePopulator(ApplicationId appId,
+ OpenstackInterfaceService openstackService,
+ FlowObjectiveService flowObjectiveService,
+ DeviceService deviceService,
+ DriverService driverService,
+ OpenstackNodeService nodeService,
ScalableGatewayService gatewayService) {
this.appId = appId;
this.flowObjectiveService = flowObjectiveService;
this.openstackService = checkNotNull(openstackService);
this.deviceService = deviceService;
this.driverService = driverService;
- this.config = config;
this.gatewayService = gatewayService;
+ this.nodeService = nodeService;
}
/**
@@ -201,7 +205,8 @@
private Port getPortOfExternalInterface() {
return deviceService.getPorts(getGatewayNode().id()).stream()
- .filter(p -> p.annotations().value(PORTNAME).equals(config.gatewayExternalInterfaceName()))
+ .filter(p -> p.annotations().value(PORTNAME)
+ .equals(org.onosproject.openstacknode.Constants.PATCH_INTG_BRIDGE))
.findAny().orElse(null);
}
@@ -239,7 +244,8 @@
getGatewayNodeList().forEach(node -> {
DeviceId deviceId = node.id();
- tBuilder.extension(buildNiciraExtenstion(deviceId, getHostIpfromOpenstackPort(openstackPort)), deviceId)
+ tBuilder.extension(buildNiciraExtenstion(deviceId,
+ getHostIpfromOpenstackPort(openstackPort).getIp4Address()), deviceId)
.setOutput(getTunnelPort(deviceId));
ForwardingObjective fo = DefaultForwardingObjective.builder()
@@ -262,9 +268,16 @@
return devices;
}
- private Ip4Address getHostIpfromOpenstackPort(OpenstackPort openstackPort) {
+ private IpAddress getHostIpfromOpenstackPort(OpenstackPort openstackPort) {
Device device = getDevicefromOpenstackPort(openstackPort);
- return config.nodes().get(device.id());
+
+ Optional<IpAddress> ipAddress = nodeService.dataIp(device.id());
+ if (!ipAddress.isPresent()) {
+ log.warn("No IP address found for device {}", device.id());
+ return null;
+ }
+
+ return ipAddress.get();
}
private Device getDevicefromOpenstackPort(OpenstackPort openstackPort) {
@@ -349,7 +362,7 @@
sBuilder.matchEthType(Ethernet.TYPE_IPV4)
.matchTunnelId(vni)
- .matchEthDst(GATEWAYMAC);
+ .matchEthDst(Constants.GATEWAY_MAC);
tBuilder.setOutput(PortNumber.CONTROLLER);
ForwardingObjective fo = DefaultForwardingObjective.builder()
@@ -365,7 +378,7 @@
private void populateComputeNodeRules(long vni) {
StreamSupport.stream(deviceService.getDevices().spliterator(), false)
- .filter(d -> !checkGatewayNode(d.id()))
+ .filter(d -> isTypeOf(d.id(), OpenstackNodeService.NodeType.COMPUTE))
.forEach(d -> populateRuleToGatewayBySgw(d.id(),
gatewayService.getGroupIdForGatewayLoadBalance(d.id()), vni));
}
@@ -376,7 +389,8 @@
sBuilder.matchEthType(Ethernet.TYPE_IPV4)
.matchTunnelId(vni)
- .matchEthDst(GATEWAYMAC);
+ .matchEthDst(Constants.GATEWAY_MAC);
+
tBuilder.group(groupId);
ForwardingObjective fo = DefaultForwardingObjective.builder()
@@ -390,14 +404,15 @@
flowObjectiveService.forward(deviceId, fo);
}
+ /*
private void populateRuleToGateway(DeviceId deviceId, Device gatewayDevice, long vni) {
TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
sBuilder.matchEthType(Ethernet.TYPE_IPV4)
.matchTunnelId(vni)
- .matchEthDst(GATEWAYMAC);
- tBuilder.extension(buildNiciraExtenstion(deviceId, config.nodes().get(gatewayDevice.id())), deviceId)
+ .matchEthDst(Constants.GATEWAY_MAC);
+ tBuilder.extension(buildNiciraExtenstion(deviceId, nodeService.nodes().get(gatewayDevice.id())), deviceId)
.setOutput(getTunnelPort(deviceId));
ForwardingObjective fo = DefaultForwardingObjective.builder()
@@ -410,13 +425,36 @@
flowObjectiveService.forward(deviceId, fo);
}
+ */
private Device getGatewayNode() {
- return checkNotNull(deviceService.getDevice(DeviceId.deviceId(config.gatewayBridgeId())));
+
+ // TODO Return the correct gateway node
+ Optional<OpenstackNode> gwNode = nodeService.nodes().stream()
+ .filter(n -> n.type().equals(OpenstackNodeService.NodeType.GATEWAY))
+ .findFirst();
+
+ if (!gwNode.isPresent()) {
+ log.warn("No Gateway is defined.");
+ return null;
+ }
+
+ return deviceService.getDevice(gwNode.get().intBridge());
}
- private boolean checkGatewayNode(DeviceId deviceId) {
- return gatewayService.getGatewayDeviceIds().stream().anyMatch(dId -> dId.equals(deviceId));
+ private boolean isTypeOf(DeviceId deviceId, OpenstackNodeService.NodeType type) {
+
+ Optional<OpenstackNode> node = nodeService.nodes().stream()
+ .filter(n -> n.intBridge().equals(deviceId) ||
+ (n.routerBridge().isPresent() && n.routerBridge().get().equals(deviceId)))
+ .filter(n -> n.type().equals(type))
+ .findFirst();
+
+ if (node.isPresent()) {
+ return true;
+ }
+
+ return false;
}
private long getVni(String netId) {
@@ -433,11 +471,11 @@
TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
sBuilder.matchEthType(Ethernet.TYPE_IPV4)
.matchTunnelId(getVni(openstackSubnet.networkId()))
- .matchEthDst(GATEWAYMAC);
+ .matchEthDst(Constants.GATEWAY_MAC);
StreamSupport.stream(deviceService.getDevices().spliterator(), false)
.forEach(d -> {
- ForwardingObjective.Flag flag = checkGatewayNode(d.id()) ?
+ ForwardingObjective.Flag flag = isTypeOf(d.id(), OpenstackNodeService.NodeType.GATEWAY) ?
ForwardingObjective.Flag.VERSATILE :
ForwardingObjective.Flag.SPECIFIC;
removeRule(d.id(), sBuilder, flag, ROUTING_RULE_PRIORITY);
@@ -474,33 +512,35 @@
}
private void populateFloatingIpIncomingRules(OpenstackFloatingIP floatingIP, OpenstackPort port) {
- DeviceId portDeviceId = getDevicefromOpenstackPort(port).id();
-
TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
sBuilder.matchEthType(Ethernet.TYPE_IPV4)
.matchIPDst(IpPrefix.valueOf(floatingIP.floatingIpAddress(), PREFIX_LENGTH));
- getGatewayNodeList().forEach(device -> {
- DeviceId deviceId = device.id();
- tBuilder.setEthSrc(GATEWAYMAC)
- .setEthDst(port.macAddress())
- .setIpDst(floatingIP.fixedIpAddress())
- .setTunnelId(getVni(port.networkId()))
- .extension(buildNiciraExtenstion(deviceId, config.nodes().get(portDeviceId)), deviceId)
- .setOutput(getTunnelPort(deviceId));
+ DeviceId gatewayDeviceId = DeviceId.deviceId(port.deviceId());
+ Optional<IpAddress> ipAddress = nodeService.dataIp(gatewayDeviceId);
+ if (!ipAddress.isPresent()) {
+ log.warn("No IP address found for device {}", port.deviceId());
+ return;
+ }
+ tBuilder.setEthSrc(Constants.GATEWAY_MAC)
+ .setEthDst(port.macAddress())
+ .setIpDst(floatingIP.fixedIpAddress())
+ .setTunnelId(getVni(port.networkId()))
+ .extension(buildNiciraExtenstion(gatewayDeviceId,
+ ipAddress.get().getIp4Address()), gatewayDeviceId)
+ .setOutput(getTunnelPort(gatewayDeviceId));
- ForwardingObjective fo = DefaultForwardingObjective.builder()
- .withSelector(sBuilder.build())
- .withTreatment(tBuilder.build())
- .withFlag(ForwardingObjective.Flag.VERSATILE)
- .withPriority(FLOATING_RULE_PRIORITY)
- .fromApp(appId)
- .add();
+ ForwardingObjective fo = DefaultForwardingObjective.builder()
+ .withSelector(sBuilder.build())
+ .withTreatment(tBuilder.build())
+ .withFlag(ForwardingObjective.Flag.VERSATILE)
+ .withPriority(FLOATING_RULE_PRIORITY)
+ .fromApp(appId)
+ .add();
- flowObjectiveService.forward(deviceId, fo);
- });
+ flowObjectiveService.forward(getGatewayNode().id(), fo);
}
private void populateFloatingIpOutgoingRules(OpenstackFloatingIP floatingIP, OpenstackPort port) {
@@ -514,6 +554,8 @@
getGatewayNodeList().forEach(device -> {
DeviceId deviceId = device.id();
tBuilder.setIpSrc(floatingIP.floatingIpAddress())
+ .setEthSrc(Constants.GW_EXT_INT_MAC)
+ .setEthDst(Constants.PHY_ROUTER_MAC)
.setOutput(getExternalPortNum(deviceId));
ForwardingObjective fo = DefaultForwardingObjective.builder()
@@ -535,19 +577,20 @@
/**
* Removes flow rules for floating ip configuration.
*
- * @param floatingIP Corresponding floating ip information
- * @param portInfo stored information about deleted vm
+ * @param floatingIp Corresponding floating ip information
+ * @param host host information for vm to remove
*/
- public void removeFloatingIpRules(OpenstackFloatingIP floatingIP, OpenstackPortInfo portInfo) {
+ public void removeFloatingIpRules(OpenstackFloatingIP floatingIp, Host host) {
TrafficSelector.Builder sOutgoingBuilder = DefaultTrafficSelector.builder();
TrafficSelector.Builder sIncomingBuilder = DefaultTrafficSelector.builder();
+ // XXX FloatingIp.tenant_id() == host.vxlan_id ???
sOutgoingBuilder.matchEthType(Ethernet.TYPE_IPV4)
- .matchTunnelId(portInfo.vni())
- .matchIPSrc(IpPrefix.valueOf(portInfo.ip(), PREFIX_LENGTH));
+ .matchTunnelId(Integer.parseInt(host.annotations().value(Constants.VXLAN_ID)))
+ .matchIPSrc(IpPrefix.valueOf(floatingIp.fixedIpAddress(), PREFIX_LENGTH));
sIncomingBuilder.matchEthType(Ethernet.TYPE_IPV4)
- .matchIPDst(IpPrefix.valueOf(floatingIP.floatingIpAddress(), PREFIX_LENGTH));
+ .matchIPDst(IpPrefix.valueOf(floatingIp.floatingIpAddress(), PREFIX_LENGTH));
getGatewayNodeList().forEach(device -> {
removeRule(device.id(), sOutgoingBuilder, ForwardingObjective.Flag.VERSATILE, FLOATING_RULE_PRIORITY);
@@ -580,8 +623,9 @@
populateL3RulestoSameNode(vmIp, openstackPort, port, device, vni);
deviceService.getAvailableDevices().forEach(d -> {
- if (!d.equals(device) && !checkGatewayNode(d.id())) {
- populateL3RulestoDifferentNode(vmIp, vni, d.id(), getHostIpfromOpenstackPort(openstackPort));
+ if (!d.equals(device) && !d.equals(getGatewayNode())) {
+ populateL3RulestoDifferentNode(vmIp, vni, d.id(),
+ getHostIpfromOpenstackPort(openstackPort).getIp4Address());
}
});
@@ -654,7 +698,7 @@
OpenstackRoutingService routingService = getService(OpenstackRoutingService.class);
deviceService.getAvailableDevices().forEach(d -> {
- if (!checkGatewayNode(d.id())) {
+ if (isTypeOf(d.id(), OpenstackNodeService.NodeType.COMPUTE)) {
routerInterfaces.forEach(routerInterface -> {
String networkId = routingService.networkIdForRouterInterface(routerInterface.portId());
long vni = getVni(networkId);