[ONOS-3948] Seperate mgmt and data network in OpenstackSwitching/RoutingService
- Supports the seperation of management and data network
Change-Id: I178dbe2af241123c5181f94a7b46fc15b4cb37c7
diff --git a/apps/openstacknetworking/openstackrouting/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingConfig.java b/apps/openstacknetworking/openstackrouting/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingConfig.java
index 74f563f..7c9f126 100644
--- a/apps/openstacknetworking/openstackrouting/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingConfig.java
+++ b/apps/openstacknetworking/openstackrouting/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingConfig.java
@@ -15,10 +15,16 @@
*/
package org.onosproject.openstacknetworking.routing;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Maps;
+import org.onlab.packet.Ip4Address;
import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.config.Config;
import org.slf4j.Logger;
+import java.util.Map;
+
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -31,6 +37,35 @@
public static final String GATEWAY_BRIDGE_ID = "gatewayBridgeId";
public static final String GATEWAY_EXTERNAL_INTERFACE_NAME = "gatewayExternalInterfaceName";
public static final String GATEWAY_EXTERNAL_INTERFACE_MAC = "gatewayExternalInterfaceMac";
+ public static final String NODES = "nodes";
+ public static final String DATAPLANE_IP = "dataPlaneIp";
+ public static final String BRIDGE_ID = "bridgeId";
+
+
+ /**
+ * Returns the data plane IP map of nodes read from network config.
+ *
+ * @return data plane IP map
+ */
+ public Map<DeviceId, Ip4Address> nodes() {
+ Map<DeviceId, Ip4Address> nodeMap = Maps.newHashMap();
+
+ JsonNode jsonNodes = object.get(NODES);
+ if (jsonNodes == null) {
+ log.error("There's no node information");
+ return null;
+ }
+
+ jsonNodes.forEach(jsonNode -> {
+ try {
+ nodeMap.putIfAbsent(DeviceId.deviceId(jsonNode.path(BRIDGE_ID).asText()),
+ Ip4Address.valueOf(jsonNode.path(DATAPLANE_IP).asText()));
+ } catch (IllegalArgumentException | NullPointerException e) {
+ log.error("Failed to read {}", e.toString());
+ }
+ });
+ return nodeMap;
+ }
/**
* Returns physical router mac.
@@ -38,7 +73,7 @@
* @return physical router mac
*/
public String physicalRouterMac() {
- return this.get("physicalRouterMac", "");
+ return this.get(PHYSICAL_ROUTER_MAC, "");
}
/**
@@ -47,7 +82,7 @@
* @return bridge id
*/
public String gatewayBridgeId() {
- return this.get("gatewayBridgeId", "");
+ return this.get(GATEWAY_BRIDGE_ID, "");
}
/**
@@ -56,7 +91,7 @@
* @return external interface name
*/
public String gatewayExternalInterfaceName() {
- return this.get("gatewayExternalInterfaceName", "");
+ return this.get(GATEWAY_EXTERNAL_INTERFACE_NAME, "");
}
/**
@@ -65,6 +100,6 @@
* @return external interface mac
*/
public String gatewayExternalInterfaceMac() {
- return this.get("gatewayExternalInterfaceMac", "");
+ return this.get(GATEWAY_EXTERNAL_INTERFACE_MAC, "");
}
}
diff --git a/apps/openstacknetworking/openstackrouting/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java b/apps/openstacknetworking/openstackrouting/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java
index 52a74c5..891b622 100644
--- a/apps/openstacknetworking/openstackrouting/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java
+++ b/apps/openstacknetworking/openstackrouting/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingManager.java
@@ -62,6 +62,8 @@
import java.util.Collection;
import java.util.List;
+import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
@@ -108,6 +110,7 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
+
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>
@@ -117,6 +120,7 @@
private static final String DEVICE_OWNER_ROUTER_INTERFACE = "network:router_interface";
private static final String FLOATING_IP_MAP_NAME = "openstackrouting-floatingip";
private static final String TP_PORT_MAP_NAME = "openstackrouting-portnum";
+ private static final String COLON = ":";
private static final int PNAT_PORT_EXPIRE_TIME = 1200 * 1000;
private static final int TP_PORT_MINIMUM_NUM = 1024;
private static final int TP_PORT_MAXIMUM_NUM = 65535;
@@ -154,6 +158,7 @@
private OpenstackIcmpHandler openstackIcmpHandler;
private OpenstackRoutingArpHandler openstackArpHandler;
private OpenstackRoutingRulePopulator rulePopulator;
+ private Map<DeviceId, Ip4Address> computeNodeMap;
@Activate
protected void activate() {
@@ -314,7 +319,7 @@
}
private void reloadInitL3Rules() {
- l3EventExecutorService.submit(() ->
+ l3EventExecutorService.execute(() ->
openstackService.ports()
.stream()
.filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE))
@@ -359,7 +364,7 @@
switch (iPacket.getProtocol()) {
case IPv4.PROTOCOL_ICMP:
- icmpEventExecutorService.submit(() ->
+ icmpEventExecutorService.execute(() ->
openstackIcmpHandler.processIcmpPacket(context, ethernet));
break;
case IPv4.PROTOCOL_UDP:
@@ -371,20 +376,21 @@
}
default:
int portNum = getPortNum(ethernet.getSourceMAC(), iPacket.getDestinationAddress());
- Port port =
+ Optional<Port> port =
getExternalPort(pkt.receivedFrom().deviceId(), config.gatewayExternalInterfaceName());
- if (port == null) {
+
+ if (!port.isPresent()) {
log.warn("There`s no external interface");
- break;
+ } else {
+ OpenstackPort openstackPort = getOpenstackPort(ethernet.getSourceMAC(),
+ Ip4Address.valueOf(iPacket.getSourceAddress()));
+ l3EventExecutorService.execute(new OpenstackPnatHandler(rulePopulator, context,
+ portNum, openstackPort, port.get(), config));
}
- OpenstackPort openstackPort = getOpenstackPort(ethernet.getSourceMAC(),
- Ip4Address.valueOf(iPacket.getSourceAddress()));
- l3EventExecutorService.execute(new OpenstackPnatHandler(rulePopulator, context,
- portNum, openstackPort, port, config));
break;
}
} else if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
- arpEventExecutorService.submit(() ->
+ arpEventExecutorService.execute(() ->
openstackArpHandler.processArpPacketFromRouter(context, ethernet));
}
}
@@ -395,7 +401,7 @@
clearPortNumMap();
portNum = findUnusedPortNum();
}
- tpPortNumMap.put(portNum, sourceMac.toString().concat(":").concat(String.valueOf(destinationAddress)));
+ tpPortNumMap.put(portNum, sourceMac.toString().concat(COLON).concat(String.valueOf(destinationAddress)));
return portNum;
}
@@ -418,12 +424,11 @@
});
}
- private Port getExternalPort(DeviceId deviceId, String interfaceName) {
+ private Optional<Port> getExternalPort(DeviceId deviceId, String interfaceName) {
return deviceService.getPorts(deviceId)
.stream()
.filter(p -> p.annotations().value(PORT_NAME).equals(interfaceName))
- .findAny()
- .orElse(null);
+ .findAny();
}
private void checkExternalConnection(OpenstackRouter router,
@@ -436,33 +441,26 @@
log.debug("Not satisfied to set pnat configuration");
return;
}
- if (router.id() == null) {
- interfaces.forEach(i -> initiateL3Rule(getRouterfromExternalIp(externalIp), i));
- } else {
- interfaces.forEach(i -> initiateL3Rule(router, i));
- }
-
+ interfaces.forEach(this::initiateL3Rule);
}
- private OpenstackRouter getRouterfromExternalIp(Ip4Address externalIp) {
- OpenstackRouter router = getExternalRouter(true)
+ private Optional<OpenstackRouter> getRouterfromExternalIp(Ip4Address externalIp) {
+ return getExternalRouter(true)
.stream()
.filter(r -> r.gatewayExternalInfo()
.externalFixedIps()
.values()
.stream()
- .findFirst()
- .orElse(null)
+ .findAny()
+ .get()
.equals(externalIp))
- .findAny()
- .orElse(null);
- return checkNotNull(router);
+ .findAny();
}
- private void initiateL3Rule(OpenstackRouter router, OpenstackRouterInterface routerInterface) {
+ private void initiateL3Rule(OpenstackRouterInterface routerInterface) {
long vni = Long.parseLong(openstackService.network(openstackService
.port(routerInterface.portId()).networkId()).segmentId());
- rulePopulator.populateExternalRules(vni, router, routerInterface);
+ rulePopulator.populateExternalRules(vni);
}
private Collection<OpenstackRouterInterface> getOpenstackRouterInterface(OpenstackRouter router) {
@@ -472,8 +470,7 @@
.filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE))
.filter(p -> p.deviceId().equals(router.id()))
.forEach(p -> {
- OpenstackRouterInterface routerInterface = portToRouterInterface(p);
- interfaces.add(routerInterface);
+ interfaces.add(portToRouterInterface(p));
});
return interfaces;
}
@@ -529,9 +526,6 @@
if (event.type().equals(NetworkConfigEvent.Type.CONFIG_ADDED) ||
event.type().equals(NetworkConfigEvent.Type.CONFIG_UPDATED)) {
l3EventExecutorService.execute(OpenstackRoutingManager.this::readConfiguration);
- rulePopulator = new OpenstackRoutingRulePopulator(appId,
- openstackService, flowObjectiveService, deviceService, driverService, config);
-
}
}
}
diff --git a/apps/openstacknetworking/openstackrouting/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingRulePopulator.java b/apps/openstacknetworking/openstackrouting/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingRulePopulator.java
index 30f439b..d8d56e6 100644
--- a/apps/openstacknetworking/openstackrouting/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingRulePopulator.java
+++ b/apps/openstacknetworking/openstackrouting/src/main/java/org/onosproject/openstacknetworking/routing/OpenstackRoutingRulePopulator.java
@@ -49,7 +49,6 @@
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.openstackinterface.OpenstackInterfaceService;
import org.onosproject.openstackinterface.OpenstackPort;
-import org.onosproject.openstackinterface.OpenstackRouter;
import org.onosproject.openstackinterface.OpenstackRouterInterface;
import org.onosproject.openstackinterface.OpenstackSubnet;
import org.onosproject.openstackinterface.OpenstackFloatingIP;
@@ -82,11 +81,11 @@
private static final String PORTNOTNULL = "Port can not be null";
private static final String DEVICENOTNULL = "Device can not be null";
private static final String TUNNEL_DESTINATION = "tunnelDst";
- private static final String DEVICE_ANNOTATION_CHANNELID = "channelId";
private static final int ROUTING_RULE_PRIORITY = 25000;
private static final int FLOATING_RULE_PRIORITY = 42000;
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;
@@ -94,8 +93,6 @@
private int portNum;
private MacAddress externalInterface;
private MacAddress externalRouter;
- private OpenstackRouter router;
- private OpenstackRouterInterface routerInterface;
/**
* The constructor of openstackRoutingRulePopulator.
@@ -247,7 +244,7 @@
private Ip4Address getHostIpfromOpenstackPort(OpenstackPort openstackPort) {
Device device = getDevicefromOpenstackPort(openstackPort);
- return getIPAddressforDevice(device);
+ return config.nodes().get(device.id());
}
private Device getDevicefromOpenstackPort(OpenstackPort openstackPort) {
@@ -266,7 +263,7 @@
.filter(p -> p.isEnabled() && p.annotations().value(PORTNAME).equals(openstackPortName))
.findAny()
.orElse(null);
- return port != null ? true : false;
+ return port != null;
}
/**
@@ -317,13 +314,8 @@
* Populates flow rules from openstackComputeNode to GatewayNode.
*
* @param vni Target network
- * @param router corresponding router
- * @param routerInterface corresponding routerInterface
*/
- public void populateExternalRules(long vni, OpenstackRouter router,
- OpenstackRouterInterface routerInterface) {
- this.router = router;
- this.routerInterface = routerInterface;
+ public void populateExternalRules(long vni) {
// 1. computeNode to gateway
populateComputeNodeRules(vni);
@@ -367,7 +359,7 @@
sBuilder.matchEthType(Ethernet.TYPE_IPV4)
.matchTunnelId(vni)
.matchEthDst(GATEWAYMAC);
- tBuilder.extension(buildNiciraExtenstion(d.id(), getIPAddressforDevice(gatewayDevice)), d.id())
+ tBuilder.extension(buildNiciraExtenstion(d.id(), config.nodes().get(gatewayDevice.id())), d.id())
.setOutput(getTunnelPort(d.id()));
ForwardingObjective fo = DefaultForwardingObjective.builder()
@@ -381,10 +373,6 @@
flowObjectiveService.forward(d.id(), fo);
}
- private Ip4Address getIPAddressforDevice(Device device) {
- return Ip4Address.valueOf(device.annotations().value(DEVICE_ANNOTATION_CHANNELID).split(":")[0]);
- }
-
private Device getGatewayNode() {
return checkNotNull(deviceService.getDevice(DeviceId.deviceId(config.gatewayBridgeId())));
}
@@ -411,11 +399,10 @@
StreamSupport.stream(deviceService.getDevices().spliterator(), false)
.forEach(d -> {
- if (checkGatewayNode(d.id())) {
- removeRule(d.id(), sBuilder, ForwardingObjective.Flag.VERSATILE, ROUTING_RULE_PRIORITY);
- } else {
- removeRule(d.id(), sBuilder, ForwardingObjective.Flag.SPECIFIC, ROUTING_RULE_PRIORITY);
- }
+ ForwardingObjective.Flag flag = checkGatewayNode(d.id()) ?
+ ForwardingObjective.Flag.VERSATILE : ForwardingObjective.Flag.SPECIFIC;
+
+ removeRule(d.id(), sBuilder, flag, ROUTING_RULE_PRIORITY);
});
}
@@ -457,13 +444,14 @@
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
sBuilder.matchEthType(Ethernet.TYPE_IPV4)
- .matchIPDst(IpPrefix.valueOf(floatingIP.floatingIpAddress(), 32));
+ .matchIPDst(IpPrefix.valueOf(floatingIP.floatingIpAddress(), PREFIX_LENGTH));
tBuilder.setEthSrc(MacAddress.valueOf(config.gatewayExternalInterfaceMac()))
.setEthDst(port.macAddress())
.setIpDst(floatingIP.fixedIpAddress())
.setTunnelId(getVni(port.networkId()))
- .extension(buildNiciraExtenstion(gatewayNode.id(), getIPAddressforDevice(portNode)), gatewayNode.id())
+ .extension(buildNiciraExtenstion(gatewayNode.id(),
+ config.nodes().get(portNode.id())), gatewayNode.id())
.setOutput(getTunnelPort(gatewayNode.id()));
ForwardingObjective fo = DefaultForwardingObjective.builder()
@@ -516,10 +504,10 @@
sOutgoingBuilder.matchEthType(Ethernet.TYPE_IPV4)
.matchTunnelId(portInfo.vni())
- .matchIPSrc(IpPrefix.valueOf(portInfo.ip(), 32));
+ .matchIPSrc(IpPrefix.valueOf(portInfo.ip(), PREFIX_LENGTH));
sIncomingBuilder.matchEthType(Ethernet.TYPE_IPV4)
- .matchIPDst(IpPrefix.valueOf(floatingIP.floatingIpAddress(), 32));
+ .matchIPDst(IpPrefix.valueOf(floatingIP.floatingIpAddress(), PREFIX_LENGTH));
removeRule(getGatewayNode().id(), sOutgoingBuilder, ForwardingObjective.Flag.VERSATILE, FLOATING_RULE_PRIORITY);
removeRule(getGatewayNode().id(), sIncomingBuilder, ForwardingObjective.Flag.VERSATILE, FLOATING_RULE_PRIORITY);