[ONOS-7444] Optimize SONA gw doesn't use vrouter app and quagga anymore
- Done: Deriving MAC address from external peer router, SNAT, Floating IP-based routing, SNAT with VLAN,
Floating IP-based routing with VLAN
- Todo: GW loadbalancing
Change-Id: Ic3dee387e8b6215b5398691665135a00475a306c
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/OpenstackNetworkAdminService.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/OpenstackNetworkAdminService.java
index fe28d32..b560b8d 100644
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/OpenstackNetworkAdminService.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/OpenstackNetworkAdminService.java
@@ -15,8 +15,13 @@
*/
package org.onosproject.openstacknetworking.api;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.openstack4j.model.network.ExternalGateway;
import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.Port;
+import org.openstack4j.model.network.Router;
import org.openstack4j.model.network.Subnet;
/**
@@ -91,4 +96,52 @@
* Clears the existing network, subnet and port states.
*/
void clear();
+
+ /**
+ * Derives external router mac address with supplied external gateway.
+ *
+ * @param externalGateway external gateway information
+ * @param router router which owns externalGateway
+ * @param vlanId vlan id of external network
+ */
+ void deriveExternalPeerRouterMac(ExternalGateway externalGateway, Router router, VlanId vlanId);
+
+ /**
+ * Deletes external router with supplied external gateway.
+ *
+ * @param externalGateway external gateway information
+ */
+ void deleteExternalPeerRouter(ExternalGateway externalGateway);
+
+ /**
+ * Deletes external router with supplied ip address.
+ *
+ * @param ipAddress ip address
+ */
+ void deleteExternalPeerRouter(String ipAddress);
+
+ /**
+ * Updates external router mac address with supplied ip address.
+ *
+ * @param ipAddress ip address
+ * @param macAddress mac address
+ */
+ void updateExternalPeerRouterMac(IpAddress ipAddress, MacAddress macAddress);
+
+ /**
+ * Updates external router vlan id with supplied ip address.
+ *
+ * @param ipAddress ip address
+ * @param vlanId vlan id
+ */
+ void updateExternalPeerRouterVlan(IpAddress ipAddress, VlanId vlanId);
+
+ /**
+ * Updates external router ith supplied ip address, mac address, vlan id.
+ *
+ * @param ipAddress ip address
+ * @param macAddress mac address
+ * @param vlanId vlan id
+ */
+ void updateExternalPeerRouter(IpAddress ipAddress, MacAddress macAddress, VlanId vlanId);
}
diff --git a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/OpenstackNetworkService.java b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/OpenstackNetworkService.java
index 7ff07bf..7b192f1 100644
--- a/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/OpenstackNetworkService.java
+++ b/apps/openstacknetworking/api/src/main/java/org/onosproject/openstacknetworking/api/OpenstackNetworkService.java
@@ -17,12 +17,10 @@
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
import org.onosproject.event.ListenerService;
import org.openstack4j.model.network.ExternalGateway;
import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.Port;
-import org.openstack4j.model.network.Router;
import org.openstack4j.model.network.Subnet;
import java.util.Set;
@@ -102,54 +100,6 @@
Set<Port> ports(String networkId);
/**
- * Derives external router mac address with supplied external gateway.
- *
- * @param externalGateway external gateway information
- * @param router router which owns externalGateway
- * @param vlanId vlan id of external network
- */
- void deriveExternalPeerRouterMac(ExternalGateway externalGateway, Router router, VlanId vlanId);
-
- /**
- * Deletes external router with supplied external gateway.
- *
- * @param externalGateway external gateway information
- */
- void deleteExternalPeerRouter(ExternalGateway externalGateway);
-
- /**
- * Deletes external router with supplied ip address.
- *
- * @param ipAddress ip address
- */
- void deleteExternalPeerRouter(String ipAddress);
-
- /**
- * Updates external router mac address with supplied ip address.
- *
- * @param ipAddress ip address
- * @param macAddress mac address
- */
- void updateExternalPeerRouterMac(IpAddress ipAddress, MacAddress macAddress);
-
- /**
- * Updates external router vlan id with supplied ip address.
- *
- * @param ipAddress ip address
- * @param vlanId vlan id
- */
- void updateExternalPeerRouterVlan(IpAddress ipAddress, VlanId vlanId);
-
- /**
- * Updates external router ith supplied ip address, mac address, vlan id.
- *
- * @param ipAddress ip address
- * @param macAddress mac address
- * @param vlanId vlan id
- */
- void updateExternalPeerRouter(IpAddress ipAddress, MacAddress macAddress, VlanId vlanId);
-
- /**
* Returns external router mac with supplied external gateway.
*
* @param externalGateway external gateway information
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/DeleteExternalPeerRouterCommand.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/DeleteExternalPeerRouterCommand.java
index efda0ae..551a871 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/DeleteExternalPeerRouterCommand.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/DeleteExternalPeerRouterCommand.java
@@ -20,7 +20,7 @@
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
-import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
import java.util.List;
@@ -39,7 +39,7 @@
@Override
protected void execute() {
- OpenstackNetworkService service = AbstractShellCommand.get(OpenstackNetworkService.class);
+ OpenstackNetworkAdminService service = AbstractShellCommand.get(OpenstackNetworkAdminService.class);
if (service.externalPeerRouters().stream()
.noneMatch(router -> router.externalPeerRouterIp().toString().equals(ipAddress))) {
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/UpdateExternalPeerRouterCommand.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/UpdateExternalPeerRouterCommand.java
index 15a7555..5667fa8 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/UpdateExternalPeerRouterCommand.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/UpdateExternalPeerRouterCommand.java
@@ -24,7 +24,7 @@
import org.onlab.packet.VlanId;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
-import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
import java.util.List;
@@ -53,7 +53,7 @@
@Override
protected void execute() {
- OpenstackNetworkService service = AbstractShellCommand.get(OpenstackNetworkService.class);
+ OpenstackNetworkAdminService service = AbstractShellCommand.get(OpenstackNetworkAdminService.class);
IpAddress externalPeerIpAddress = IpAddress.valueOf(
IpAddress.Version.INET, Ip4Address.valueOf(ipAddress).toOctets());
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/UpdateExternalPeerRouterVlanCommand.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/UpdateExternalPeerRouterVlanCommand.java
index e0aae53..3dc14a7 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/UpdateExternalPeerRouterVlanCommand.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/UpdateExternalPeerRouterVlanCommand.java
@@ -23,7 +23,7 @@
import org.onlab.packet.VlanId;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
-import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
import org.onosproject.openstacknetworking.api.OpenstackRouterService;
import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.Router;
@@ -51,29 +51,29 @@
@Override
protected void execute() {
- OpenstackNetworkService osNetService = AbstractShellCommand.get(OpenstackNetworkService.class);
+ OpenstackNetworkAdminService osNetAdminService = AbstractShellCommand.get(OpenstackNetworkAdminService.class);
OpenstackRouterService osRouterService = AbstractShellCommand.get(OpenstackRouterService.class);
IpAddress externalPeerIpAddress = IpAddress.valueOf(
IpAddress.Version.INET, Ip4Address.valueOf(ipAddress).toOctets());
- if (osNetService.externalPeerRouters().isEmpty()) {
+ if (osNetAdminService.externalPeerRouters().isEmpty()) {
print(NO_ELEMENT);
return;
- } else if (osNetService.externalPeerRouters().stream()
+ } else if (osNetAdminService.externalPeerRouters().stream()
.noneMatch(router -> router.externalPeerRouterIp().toString().equals(ipAddress))) {
print(NO_ELEMENT);
return;
}
- Subnet subnet = osNetService.subnets().stream()
+ Subnet subnet = osNetAdminService.subnets().stream()
.filter(s -> s.getGateway().equals(ipAddress))
.findAny().orElse(null);
if (subnet == null) {
return;
}
- Network network = osNetService.network(subnet.getNetworkId());
+ Network network = osNetAdminService.network(subnet.getNetworkId());
if (network == null) {
return;
}
@@ -88,11 +88,11 @@
try {
if (vlanId.equals(NONE)) {
- osNetService.updateExternalPeerRouterVlan(externalPeerIpAddress, VlanId.NONE);
- osNetService.deriveExternalPeerRouterMac(router.getExternalGatewayInfo(), router, VlanId.NONE);
+ osNetAdminService.updateExternalPeerRouterVlan(externalPeerIpAddress, VlanId.NONE);
+ osNetAdminService.deriveExternalPeerRouterMac(router.getExternalGatewayInfo(), router, VlanId.NONE);
} else {
- osNetService.updateExternalPeerRouterVlan(externalPeerIpAddress, VlanId.vlanId(vlanId));
- osNetService.deriveExternalPeerRouterMac(
+ osNetAdminService.updateExternalPeerRouterVlan(externalPeerIpAddress, VlanId.vlanId(vlanId));
+ osNetAdminService.deriveExternalPeerRouterMac(
router.getExternalGatewayInfo(), router, VlanId.vlanId(vlanId));
}
@@ -101,7 +101,7 @@
}
print(FORMAT, "Router IP", "Mac Address", "VLAN ID");
- List<ExternalPeerRouter> routers = Lists.newArrayList(osNetService.externalPeerRouters());
+ List<ExternalPeerRouter> routers = Lists.newArrayList(osNetAdminService.externalPeerRouters());
for (ExternalPeerRouter r: routers) {
print(FORMAT, r.externalPeerRouterIp(),
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
index 657d7a0..e6be7ef 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingArpHandler.java
@@ -35,7 +35,7 @@
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.openstacknetworking.api.Constants;
-import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
import org.onosproject.openstacknetworking.api.OpenstackRouterService;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeService;
@@ -68,7 +68,7 @@
protected PacketService packetService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected OpenstackNetworkService osNetworkService;
+ protected OpenstackNetworkAdminService osNetworkAdminService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected OpenstackRouterService osRouterService;
@@ -114,7 +114,7 @@
//In case target ip is for associated floating ip, sets target mac to vm's.
if (floatingIP != null && floatingIP.getPortId() != null) {
- targetMac = MacAddress.valueOf(osNetworkService.port(floatingIP.getPortId()).getMacAddress());
+ targetMac = MacAddress.valueOf(osNetworkAdminService.port(floatingIP.getPortId()).getMacAddress());
}
if (isExternalGatewaySourceIp(targetIp.getIp4Address())) {
@@ -147,7 +147,7 @@
try {
if (receivedPortNum.equals(
osNodeService.node(context.inPacket().receivedFrom().deviceId()).uplinkPortNum())) {
- osNetworkService.updateExternalPeerRouterMac(
+ osNetworkAdminService.updateExternalPeerRouterMac(
Ip4Address.valueOf(arp.getSenderProtocolAddress()),
MacAddress.valueOf(arp.getSenderHardwareAddress()));
}
@@ -185,7 +185,7 @@
}
private boolean isExternalGatewaySourceIp(IpAddress targetIp) {
- return osNetworkService.ports().stream()
+ return osNetworkAdminService.ports().stream()
.filter(osPort -> Objects.equals(osPort.getDeviceOwner(),
DEVICE_OWNER_ROUTER_GW))
.flatMap(osPort -> osPort.getFixedIps().stream())
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
index 16607b1..fe41bdc 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
@@ -37,6 +37,7 @@
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.openstacknetworking.api.Constants;
+import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
import org.onosproject.openstacknetworking.api.InstancePort;
import org.onosproject.openstacknetworking.api.InstancePortService;
import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
@@ -160,9 +161,15 @@
throw new IllegalStateException(error);
}
+
+ ExternalPeerRouter externalPeerRouter = externalPeerRouter(osNet);
+ if (externalPeerRouter == null) {
+ return;
+ }
+
setComputeNodeToGateway(instPort, osNet, install);
- setDownstreamRules(floatingIp, osNet, instPort, install);
- setUpstreamRules(floatingIp, osNet, instPort, install);
+ setDownstreamRules(floatingIp, osNet, instPort, externalPeerRouter, install);
+ setUpstreamRules(floatingIp, osNet, instPort, externalPeerRouter, install);
}
private void setComputeNodeToGateway(InstancePort instPort, Network osNet, boolean install) {
@@ -216,7 +223,8 @@
}
private void setDownstreamRules(NetFloatingIP floatingIp, Network osNet,
- InstancePort instPort, boolean install) {
+ InstancePort instPort, ExternalPeerRouter externalPeerRouter,
+ boolean install) {
OpenstackNode cNode = osNodeService.node(instPort.deviceId());
if (cNode == null) {
final String error = String.format("Cannot find openstack node for device %s",
@@ -235,16 +243,22 @@
}
IpAddress floating = IpAddress.valueOf(floatingIp.getFloatingIpAddress());
- TrafficSelector externalSelector = DefaultTrafficSelector.builder()
+ TrafficSelector.Builder externalSelectorBuilder = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
- .matchIPDst(floating.toIpPrefix())
- .build();
+ .matchIPDst(floating.toIpPrefix());
+
+ TrafficTreatment.Builder externalBuilder = DefaultTrafficTreatment.builder()
+ .setEthSrc(Constants.DEFAULT_GATEWAY_MAC)
+ .setEthDst(instPort.macAddress())
+ .setIpDst(instPort.ipAddress().getIp4Address());
+
+ if (!externalPeerRouter.externalPeerRouterVlanId().equals(VlanId.NONE)) {
+ externalSelectorBuilder.matchVlanId(externalPeerRouter.externalPeerRouterVlanId()).build();
+ externalBuilder.popVlan();
+ }
osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
- TrafficTreatment.Builder externalBuilder = DefaultTrafficTreatment.builder()
- .setEthSrc(Constants.DEFAULT_GATEWAY_MAC)
- .setEthDst(instPort.macAddress())
- .setIpDst(instPort.ipAddress().getIp4Address());
+
switch (osNet.getNetworkType()) {
case VXLAN:
@@ -270,7 +284,7 @@
osFlowRuleService.setRule(
appId,
gNode.intgBridge(),
- externalSelector,
+ externalSelectorBuilder.build(),
externalBuilder.build(),
PRIORITY_FLOATING_EXTERNAL,
GW_COMMON_TABLE,
@@ -321,7 +335,8 @@
}
private void setUpstreamRules(NetFloatingIP floatingIp, Network osNet,
- InstancePort instPort, boolean install) {
+ InstancePort instPort, ExternalPeerRouter externalPeerRouter,
+ boolean install) {
IpAddress floating = IpAddress.valueOf(floatingIp.getFloatingIpAddress());
TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
@@ -340,21 +355,20 @@
throw new IllegalStateException(error);
}
- MacAddress externalPeerRouterMac = externalPeerRouterMac(osNet);
- if (externalPeerRouterMac == null) {
- return;
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
+ .setIpSrc(floating.getIp4Address())
+ .setEthSrc(instPort.macAddress())
+ .setEthDst(externalPeerRouter.externalPeerRouterMac());
+
+ if (osNet.getNetworkType().equals(NetworkType.VLAN)) {
+ tBuilder.popVlan();
}
+ if (!externalPeerRouter.externalPeerRouterVlanId().equals(VlanId.NONE)) {
+ tBuilder.pushVlan().setVlanId(externalPeerRouter.externalPeerRouterVlanId());
+ }
osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
- TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
- .setIpSrc(floating.getIp4Address())
- .setEthSrc(instPort.macAddress())
- .setEthDst(externalPeerRouterMac);
-
- if (osNet.getNetworkType().equals(NetworkType.VLAN)) {
- tBuilder.popVlan();
- }
osFlowRuleService.setRule(
appId,
@@ -367,6 +381,32 @@
});
}
+ private ExternalPeerRouter externalPeerRouter(Network network) {
+ Subnet subnet = osNetworkService.subnet(network.getId());
+
+ if (subnet == null) {
+ return null;
+ }
+
+ RouterInterface osRouterIface = osRouterService.routerInterfaces().stream()
+ .filter(i -> Objects.equals(i.getSubnetId(), subnet.getId()))
+ .findAny().orElse(null);
+ if (osRouterIface == null) {
+ return null;
+ }
+
+ Router osRouter = osRouterService.router(osRouterIface.getId());
+ if (osRouter == null) {
+ return null;
+ }
+ if (osRouter.getExternalGatewayInfo() == null) {
+ return null;
+ }
+
+ ExternalGateway exGatewayInfo = osRouter.getExternalGatewayInfo();
+ return osNetworkService.externalPeerRouter(exGatewayInfo);
+ }
+
private MacAddress externalPeerRouterMac(Network network) {
if (network == null) {
return null;
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
index 42a3da4..94cdd42 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
@@ -55,6 +55,7 @@
import org.onosproject.openstacknetworking.api.InstancePortListener;
import org.onosproject.openstacknetworking.api.InstancePortService;
import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
import org.onosproject.openstacknetworking.api.OpenstackRouterEvent;
import org.onosproject.openstacknetworking.api.OpenstackRouterListener;
@@ -132,6 +133,9 @@
protected OpenstackNetworkService osNetworkService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected OpenstackNetworkAdminService osNetworkAdminService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected OpenstackRouterService osRouterService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -217,10 +221,10 @@
VlanId vlanId = externalPeerRouter == null ? VlanId.NONE : externalPeerRouter.externalPeerRouterVlanId();
if (exGateway == null) {
- osNetworkService.deleteExternalPeerRouter(exGateway);
+ osNetworkAdminService.deleteExternalPeerRouter(exGateway);
osRouterService.routerInterfaces(osRouter.getId()).forEach(iface -> setSourceNat(iface, false));
} else {
- osNetworkService.deriveExternalPeerRouterMac(exGateway, osRouter, vlanId);
+ osNetworkAdminService.deriveExternalPeerRouterMac(exGateway, osRouter, vlanId);
osRouterService.routerInterfaces(osRouter.getId()).forEach(iface ->
setSourceNat(iface, exGateway.isEnableSnat()));
}