[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
- Todo: Floating IP-based routing with VLAN, GW loadbalancing
Change-Id: I718b71eaf64a40049fc86687f10432446bb1b5bf
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 2974c47..7ff07bf 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
@@ -106,8 +106,9 @@
*
* @param externalGateway external gateway information
* @param router router which owns externalGateway
+ * @param vlanId vlan id of external network
*/
- void deriveExternalPeerRouterMac(ExternalGateway externalGateway, Router router);
+ void deriveExternalPeerRouterMac(ExternalGateway externalGateway, Router router, VlanId vlanId);
/**
* Deletes external router with supplied external gateway.
@@ -165,6 +166,14 @@
ExternalPeerRouter externalPeerRouter(IpAddress ipAddress);
/**
+ * Returns external router with supplied external gateway.
+ *
+ * @param externalGateway external gateway information
+ * @return external router
+ */
+ ExternalPeerRouter externalPeerRouter(ExternalGateway externalGateway);
+
+ /**
* Returns external peer router list.
*
* @return external peer router list
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 eed62e7..e0aae53 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
@@ -24,6 +24,10 @@
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
+import org.onosproject.openstacknetworking.api.OpenstackRouterService;
+import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.Router;
+import org.openstack4j.model.network.Subnet;
import java.util.List;
@@ -47,37 +51,62 @@
@Override
protected void execute() {
- OpenstackNetworkService service = AbstractShellCommand.get(OpenstackNetworkService.class);
+ OpenstackNetworkService osNetService = AbstractShellCommand.get(OpenstackNetworkService.class);
+ OpenstackRouterService osRouterService = AbstractShellCommand.get(OpenstackRouterService.class);
IpAddress externalPeerIpAddress = IpAddress.valueOf(
IpAddress.Version.INET, Ip4Address.valueOf(ipAddress).toOctets());
- if (service.externalPeerRouters().isEmpty()) {
+ if (osNetService.externalPeerRouters().isEmpty()) {
print(NO_ELEMENT);
return;
- } else if (service.externalPeerRouters().stream()
+ } else if (osNetService.externalPeerRouters().stream()
.noneMatch(router -> router.externalPeerRouterIp().toString().equals(ipAddress))) {
print(NO_ELEMENT);
return;
}
+ Subnet subnet = osNetService.subnets().stream()
+ .filter(s -> s.getGateway().equals(ipAddress))
+ .findAny().orElse(null);
+ if (subnet == null) {
+ return;
+ }
+
+ Network network = osNetService.network(subnet.getNetworkId());
+ if (network == null) {
+ return;
+ }
+
+ Router router = osRouterService.routers().stream()
+ .filter(r -> r.getExternalGatewayInfo().getNetworkId().equals(network.getId()))
+ .findAny().orElse(null);
+
+ if (router == null) {
+ return;
+ }
+
try {
if (vlanId.equals(NONE)) {
- service.updateExternalPeerRouterVlan(externalPeerIpAddress, VlanId.NONE);
+ osNetService.updateExternalPeerRouterVlan(externalPeerIpAddress, VlanId.NONE);
+ osNetService.deriveExternalPeerRouterMac(router.getExternalGatewayInfo(), router, VlanId.NONE);
} else {
- service.updateExternalPeerRouterVlan(externalPeerIpAddress, VlanId.vlanId(vlanId));
+ osNetService.updateExternalPeerRouterVlan(externalPeerIpAddress, VlanId.vlanId(vlanId));
+ osNetService.deriveExternalPeerRouterMac(
+ router.getExternalGatewayInfo(), router, VlanId.vlanId(vlanId));
+
}
} catch (IllegalArgumentException e) {
log.error("Exception occurred because of {}", e.toString());
}
print(FORMAT, "Router IP", "Mac Address", "VLAN ID");
- List<ExternalPeerRouter> routers = Lists.newArrayList(service.externalPeerRouters());
+ List<ExternalPeerRouter> routers = Lists.newArrayList(osNetService.externalPeerRouters());
- for (ExternalPeerRouter router: routers) {
- print(FORMAT, router.externalPeerRouterIp(),
- router.externalPeerRouterMac().toString(),
- router.externalPeerRouterVlanId());
+ for (ExternalPeerRouter r: routers) {
+ print(FORMAT, r.externalPeerRouterIp(),
+ r.externalPeerRouterMac().toString(),
+ r.externalPeerRouterVlanId());
}
}
}
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
index ac1e796..e67270c 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackNetworkManager.java
@@ -124,7 +124,6 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected OpenstackNodeService osNodeService;
-
private final OpenstackNetworkStoreDelegate delegate = new InternalNetworkStoreDelegate();
private ConsistentMap<String, ExternalPeerRouter> externalPeerRouterMap;
@@ -342,7 +341,22 @@
}
@Override
- public void deriveExternalPeerRouterMac(ExternalGateway externalGateway, Router router) {
+ public ExternalPeerRouter externalPeerRouter(ExternalGateway externalGateway) {
+ IpAddress ipAddress = getExternalPeerRouterIp(externalGateway);
+
+ if (ipAddress == null) {
+ return null;
+ }
+
+ if (externalPeerRouterMap.containsKey(ipAddress.toString())) {
+ return externalPeerRouterMap.get(ipAddress.toString()).value();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void deriveExternalPeerRouterMac(ExternalGateway externalGateway, Router router, VlanId vlanId) {
log.info("deriveExternalPeerRouterMac called");
IpAddress sourceIp = getExternalGatewaySourceIp(externalGateway, router);
@@ -364,7 +378,7 @@
Ethernet ethRequest = ARP.buildArpRequest(sourceMac.toBytes(),
sourceIp.toOctets(),
targetIp.toOctets(),
- VlanId.NO_VID);
+ vlanId.id());
if (osNodeService.completeNodes(OpenstackNode.NodeType.GATEWAY).isEmpty()) {
log.warn("There's no complete gateway");
@@ -400,7 +414,7 @@
ByteBuffer.wrap(ethRequest.serialize())));
externalPeerRouterMap.put(
- targetIp.toString(), new DefaultExternalPeerRouter(targetIp, MacAddress.NONE, VlanId.NONE));
+ targetIp.toString(), new DefaultExternalPeerRouter(targetIp, MacAddress.NONE, vlanId));
log.info("Initializes external peer router map with peer router IP {}", targetIp.toString());
}
@@ -428,32 +442,6 @@
}
}
- private IpAddress getExternalGatewaySourceIp(ExternalGateway externalGateway, Router router) {
- Port exGatewayPort = ports(externalGateway.getNetworkId())
- .stream()
- .filter(port -> Objects.equals(port.getDeviceId(), router.getId()))
- .findAny().orElse(null);
- if (exGatewayPort == null) {
- log.warn("no external gateway port for router({})", router.getName());
- return null;
- }
-
- IP ipAddress = exGatewayPort.getFixedIps().stream().findFirst().orElse(null);
-
- return ipAddress == null ? null : IpAddress.valueOf(ipAddress.getIpAddress());
- }
-
- private IpAddress getExternalPeerRouterIp(ExternalGateway externalGateway) {
- Optional<Subnet> externalSubnet = subnets(externalGateway.getNetworkId())
- .stream()
- .findFirst();
-
- if (externalSubnet.isPresent()) {
- return IpAddress.valueOf(externalSubnet.get().getGateway());
- } else {
- return null;
- }
- }
@Override
public void updateExternalPeerRouterMac(IpAddress ipAddress, MacAddress macAddress) {
@@ -497,9 +485,9 @@
public void updateExternalPeerRouterVlan(IpAddress ipAddress, VlanId vlanId) {
try {
- externalPeerRouterMap.computeIfPresent(ipAddress.toString(), (id, existing) -> {
- return new DefaultExternalPeerRouter(ipAddress, existing.externalPeerRouterMac(), vlanId);
- });
+ externalPeerRouterMap.computeIfPresent(ipAddress.toString(), (id, existing) ->
+ new DefaultExternalPeerRouter(ipAddress, existing.externalPeerRouterMac(), vlanId));
+
} catch (Exception e) {
log.error("Exception occurred because of {}", e.toString());
}
@@ -534,4 +522,27 @@
}
}
}
+
+ private IpAddress getExternalGatewaySourceIp(ExternalGateway externalGateway, Router router) {
+ Port exGatewayPort = ports(externalGateway.getNetworkId())
+ .stream()
+ .filter(port -> Objects.equals(port.getDeviceId(), router.getId()))
+ .findAny().orElse(null);
+ if (exGatewayPort == null) {
+ log.warn("no external gateway port for router({})", router.getName());
+ return null;
+ }
+
+ IP ipAddress = exGatewayPort.getFixedIps().stream().findFirst().orElse(null);
+
+ return ipAddress == null ? null : IpAddress.valueOf(ipAddress.getIpAddress());
+ }
+
+ private IpAddress getExternalPeerRouterIp(ExternalGateway externalGateway) {
+ Optional<Subnet> externalSubnet = subnets(externalGateway.getNetworkId())
+ .stream()
+ .findFirst();
+
+ return externalSubnet.map(subnet -> IpAddress.valueOf(subnet.getGateway())).orElse(null);
+ }
}
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 5dee134..657d7a0 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
@@ -34,8 +34,8 @@
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
-import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
import org.onosproject.openstacknetworking.api.Constants;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
import org.onosproject.openstacknetworking.api.OpenstackRouterService;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeService;
@@ -112,6 +112,7 @@
.filter(ip -> ip.getFloatingIpAddress().equals(targetIp.toString()))
.findAny().orElse(null);
+ //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());
}
@@ -128,9 +129,9 @@
Ethernet ethReply = ARP.buildArpReply(targetIp.getIp4Address(),
targetMac, ethernet);
+
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setOutput(context.inPacket().receivedFrom().port())
- .build();
+ .setOutput(context.inPacket().receivedFrom().port()).build();
packetService.emit(new DefaultOutboundPacket(
context.inPacket().receivedFrom().deviceId(),
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 6d2f70b..42a3da4 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
@@ -49,6 +49,7 @@
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.onosproject.openstacknetworking.api.Constants;
+import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
import org.onosproject.openstacknetworking.api.InstancePort;
import org.onosproject.openstacknetworking.api.InstancePortEvent;
import org.onosproject.openstacknetworking.api.InstancePortListener;
@@ -211,16 +212,17 @@
setRouterAdminRules(network.getProviderSegID(), network.getNetworkType(), !osRouter.isAdminStateUp());
});
+
+ ExternalPeerRouter externalPeerRouter = osNetworkService.externalPeerRouter(exGateway);
+ VlanId vlanId = externalPeerRouter == null ? VlanId.NONE : externalPeerRouter.externalPeerRouterVlanId();
+
if (exGateway == null) {
osNetworkService.deleteExternalPeerRouter(exGateway);
- osRouterService.routerInterfaces(osRouter.getId()).forEach(iface -> {
- setSourceNat(osRouter, iface, false);
- });
+ osRouterService.routerInterfaces(osRouter.getId()).forEach(iface -> setSourceNat(iface, false));
} else {
- osNetworkService.deriveExternalPeerRouterMac(exGateway, osRouter);
- osRouterService.routerInterfaces(osRouter.getId()).forEach(iface -> {
- setSourceNat(osRouter, iface, exGateway.isEnableSnat());
- });
+ osNetworkService.deriveExternalPeerRouterMac(exGateway, osRouter, vlanId);
+ osRouterService.routerInterfaces(osRouter.getId()).forEach(iface ->
+ setSourceNat(iface, exGateway.isEnableSnat()));
}
}
@@ -251,7 +253,7 @@
setGatewayIcmp(osSubnet, true);
ExternalGateway exGateway = osRouter.getExternalGatewayInfo();
if (exGateway != null && exGateway.isEnableSnat()) {
- setSourceNat(osRouter, osRouterIface, true);
+ setSourceNat(osRouterIface, true);
}
log.info("Connected subnet({}) to {}", osSubnet.getCidr(), osRouter.getName());
}
@@ -275,12 +277,12 @@
setGatewayIcmp(osSubnet, false);
ExternalGateway exGateway = osRouter.getExternalGatewayInfo();
if (exGateway != null && exGateway.isEnableSnat()) {
- setSourceNat(osRouter, osRouterIface, false);
+ setSourceNat(osRouterIface, false);
}
log.info("Disconnected subnet({}) from {}", osSubnet.getCidr(), osRouter.getName());
}
- private void setSourceNat(Router osRouter, RouterInterface routerIface, boolean install) {
+ private void setSourceNat(RouterInterface routerIface, boolean install) {
Subnet osSubnet = osNetworkService.subnet(routerIface.getSubnetId());
Network osNet = osNetworkService.network(osSubnet.getNetworkId());
@@ -320,8 +322,8 @@
osNodeService.completeNodes(OpenstackNode.NodeType.GATEWAY)
.forEach(gwNode -> {
- instancePortService.instancePorts(netId).stream()
- .forEach(port -> setRulesForSnatIngressRule(gwNode.intgBridge(),
+ instancePortService.instancePorts(netId)
+ .forEach(port -> setRulesForSnatIngressRule(gwNode.intgBridge(),
Long.parseLong(osNet.getProviderSegID()),
IpPrefix.valueOf(port.ipAddress(), 32),
port.deviceId(),
@@ -427,13 +429,11 @@
}
IpAddress gatewayIp = IpAddress.valueOf(osSubnet.getGateway());
- osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
+ osNodeService.completeNodes(GATEWAY).forEach(gNode ->
setGatewayIcmpRule(
gatewayIp,
gNode.intgBridge(),
- install
- );
- });
+ install));
final String updateStr = install ? MSG_ENABLED : MSG_DISABLED;
log.debug(updateStr + "ICMP to {}", osSubnet.getGateway());
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
index 13c9e18..f82b1c5 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java
@@ -26,6 +26,7 @@
import org.onlab.packet.IPv4;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
@@ -39,6 +40,7 @@
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
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.OpenstackNetworkService;
@@ -177,25 +179,25 @@
ICMP icmp) {
InstancePort instPort = instancePortService.instancePort(srcMac);
if (instPort == null) {
- log.trace(ERR_REQ + "unknown source host(MAC:{})", srcMac);
+ log.info(ERR_REQ + "unknown source host(MAC:{})", srcMac);
return;
}
IpAddress srcIp = IpAddress.valueOf(ipPacket.getSourceAddress());
Subnet srcSubnet = getSourceSubnet(instPort, srcIp);
if (srcSubnet == null) {
- log.trace(ERR_REQ + "unknown source subnet(IP:{})", srcIp);
+ log.info(ERR_REQ + "unknown source subnet(IP:{})", srcIp);
return;
}
if (Strings.isNullOrEmpty(srcSubnet.getGateway())) {
- log.trace(ERR_REQ + "source subnet(ID:{}, CIDR:{}) has no gateway",
+ log.info(ERR_REQ + "source subnet(ID:{}, CIDR:{}) has no gateway",
srcSubnet.getId(), srcSubnet.getCidr());
return;
}
- MacAddress externalPeerRouterMac = externalPeerRouterMac(srcSubnet);
- if (externalPeerRouterMac == null) {
- log.trace(ERR_REQ + "failed to get external peer router mac");
+ ExternalPeerRouter externalPeerRouter = externalPeerRouter(srcSubnet);
+ if (externalPeerRouter == null) {
+ log.info(ERR_REQ + "failed to get external peer router");
return;
}
@@ -210,7 +212,7 @@
return;
}
- sendRequestForExternal(ipPacket, srcDevice, externalIp, externalPeerRouterMac(srcSubnet));
+ sendRequestForExternal(ipPacket, srcDevice, externalIp, externalPeerRouter);
String icmpInfoKey = String.valueOf(getIcmpId(icmp))
.concat(String.valueOf(externalIp.getIp4Address().toInt()))
.concat(String.valueOf(ipPacket.getDestinationAddress()));
@@ -226,7 +228,7 @@
}
}
- private MacAddress externalPeerRouterMac(Subnet subnet) {
+ private ExternalPeerRouter externalPeerRouter(Subnet subnet) {
RouterInterface osRouterIface = osRouterService.routerInterfaces().stream()
.filter(i -> Objects.equals(i.getSubnetId(), subnet.getId()))
.findAny().orElse(null);
@@ -244,7 +246,7 @@
ExternalGateway exGatewayInfo = osRouter.getExternalGatewayInfo();
- return osNetworkService.externalPeerRouterMac(exGatewayInfo);
+ return osNetworkService.externalPeerRouter(exGatewayInfo);
}
private void handleEchoReply(IPv4 ipPacket, ICMP icmp) {
@@ -355,7 +357,7 @@
}
private void sendRequestForExternal(IPv4 ipPacket, DeviceId srcDevice,
- IpAddress srcNatIp, MacAddress externalRouterMac) {
+ IpAddress srcNatIp, ExternalPeerRouter externalPeerRouter) {
ICMP icmpReq = (ICMP) ipPacket.getPayload();
icmpReq.resetChecksum();
ipPacket.setSourceAddress(srcNatIp.getIp4Address().toInt()).resetChecksum();
@@ -364,8 +366,13 @@
Ethernet icmpRequestEth = new Ethernet();
icmpRequestEth.setEtherType(Ethernet.TYPE_IPV4)
.setSourceMACAddress(DEFAULT_GATEWAY_MAC)
- .setDestinationMACAddress(externalRouterMac)
- .setPayload(ipPacket);
+ .setDestinationMACAddress(externalPeerRouter.externalPeerRouterMac());
+
+ if (!externalPeerRouter.externalPeerRouterVlanId().equals(VlanId.NONE)) {
+ icmpRequestEth.setVlanID(externalPeerRouter.externalPeerRouterVlanId().toShort());
+ }
+
+ icmpRequestEth.setPayload(ipPacket);
OpenstackNode osNode = osNodeService.node(srcDevice);
if (osNode == null) {
@@ -386,7 +393,13 @@
}
private void processReplyFromExternal(IPv4 ipPacket, InstancePort instPort) {
+
+ if (instPort.networkId() == null) {
+ return;
+ }
+
ICMP icmpReply = (ICMP) ipPacket.getPayload();
+
icmpReply.resetChecksum();
ipPacket.setDestinationAddress(instPort.ipAddress().getIp4Address().toInt())
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
index 9f792bd..d4db5a3 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
@@ -24,7 +24,6 @@
import org.onlab.packet.IPv4;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
import org.onlab.packet.TCP;
import org.onlab.packet.TpPort;
import org.onlab.packet.UDP;
@@ -43,6 +42,7 @@
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
+import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
import org.onosproject.openstacknetworking.api.InstancePort;
import org.onosproject.openstacknetworking.api.InstancePortService;
import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
@@ -192,23 +192,24 @@
return;
}
- MacAddress externalPeerRouterMac = externalPeerRouterMac(srcSubnet);
- if (externalPeerRouterMac == null) {
+ ExternalPeerRouter externalPeerRouter = externalPeerRouter(srcSubnet);
+ if (externalPeerRouter == null) {
return;
}
populateSnatFlowRules(context.inPacket(),
srcInstPort,
TpPort.tpPort(patPort),
- externalGatewayIp, externalPeerRouterMac);
+ externalGatewayIp, externalPeerRouter);
+
packetOut(eth.duplicate(),
packetIn.receivedFrom().deviceId(),
patPort,
- externalGatewayIp, externalPeerRouterMac);
+ externalGatewayIp, externalPeerRouter);
}
- private MacAddress externalPeerRouterMac(Subnet subnet) {
+ private ExternalPeerRouter externalPeerRouter(Subnet subnet) {
RouterInterface osRouterIface = osRouterService.routerInterfaces().stream()
.filter(i -> Objects.equals(i.getSubnetId(), subnet.getId()))
.findAny().orElse(null);
@@ -225,8 +226,7 @@
}
ExternalGateway exGatewayInfo = osRouter.getExternalGatewayInfo();
-
- return osNetworkService.externalPeerRouterMac(exGatewayInfo);
+ return osNetworkService.externalPeerRouter(exGatewayInfo);
}
private Subnet getSourceSubnet(InstancePort instance, IpAddress srcIp) {
@@ -282,7 +282,7 @@
}
private void populateSnatFlowRules(InboundPacket packetIn, InstancePort srcInstPort,
- TpPort patPort, IpAddress externalIp, MacAddress externalPeerRouterMac) {
+ TpPort patPort, IpAddress externalIp, ExternalPeerRouter externalPeerRouter) {
Network osNet = osNetworkService.network(srcInstPort.networkId());
if (osNet == null) {
final String error = String.format("%s network %s not found",
@@ -294,13 +294,14 @@
osNet.getProviderSegID(),
osNet.getNetworkType(),
externalIp,
+ externalPeerRouter,
patPort,
packetIn);
setUpstreamRules(osNet.getProviderSegID(),
osNet.getNetworkType(),
externalIp,
- externalPeerRouterMac,
+ externalPeerRouter,
patPort,
packetIn);
}
@@ -308,6 +309,7 @@
private void setDownstreamRules(InstancePort srcInstPort, String segmentId,
NetworkType networkType,
IpAddress externalIp,
+ ExternalPeerRouter externalPeerRouter,
TpPort patPort,
InboundPacket packetIn) {
IPv4 iPacket = (IPv4) packetIn.parsed().getPayload();
@@ -323,6 +325,11 @@
.setEthDst(packetIn.parsed().getSourceMAC())
.setIpDst(internalIp);
+ if (!externalPeerRouter.externalPeerRouterVlanId().equals(VlanId.NONE)) {
+ sBuilder.matchVlanId(externalPeerRouter.externalPeerRouterVlanId());
+ tBuilder.popVlan();
+ }
+
switch (networkType) {
case VXLAN:
tBuilder.setTunnelId(Long.parseLong(segmentId));
@@ -389,7 +396,7 @@
}
private void setUpstreamRules(String segmentId, NetworkType networkType,
- IpAddress externalIp, MacAddress externalPeerRouterMac,
+ IpAddress externalIp, ExternalPeerRouter externalPeerRouter,
TpPort patPort,
InboundPacket packetIn) {
IPv4 iPacket = (IPv4) packetIn.parsed().getPayload();
@@ -422,20 +429,24 @@
sBuilder.matchTcpSrc(TpPort.tpPort(tcpPacket.getSourcePort()))
.matchTcpDst(TpPort.tpPort(tcpPacket.getDestinationPort()));
tBuilder.setTcpSrc(patPort)
- .setEthDst(externalPeerRouterMac);
+ .setEthDst(externalPeerRouter.externalPeerRouterMac());
break;
case IPv4.PROTOCOL_UDP:
UDP udpPacket = (UDP) iPacket.getPayload();
sBuilder.matchUdpSrc(TpPort.tpPort(udpPacket.getSourcePort()))
.matchUdpDst(TpPort.tpPort(udpPacket.getDestinationPort()));
tBuilder.setUdpSrc(patPort)
- .setEthDst(externalPeerRouterMac);
+ .setEthDst(externalPeerRouter.externalPeerRouterMac());
break;
default:
log.debug("Unsupported IPv4 protocol {}");
break;
}
+ if (!externalPeerRouter.externalPeerRouterVlanId().equals(VlanId.NONE)) {
+ tBuilder.pushVlan().setVlanId(externalPeerRouter.externalPeerRouterVlanId());
+ }
+
tBuilder.setIpSrc(externalIp);
osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
TrafficTreatment.Builder tmpBuilder =
@@ -454,7 +465,7 @@
}
private void packetOut(Ethernet ethPacketIn, DeviceId srcDevice, int patPort,
- IpAddress externalIp, MacAddress externalPeerRouterMac) {
+ IpAddress externalIp, ExternalPeerRouter externalPeerRouter) {
IPv4 iPacket = (IPv4) ethPacketIn.getPayload();
switch (iPacket.getProtocol()) {
case IPv4.PROTOCOL_TCP:
@@ -479,8 +490,14 @@
iPacket.setSourceAddress(externalIp.toString());
iPacket.resetChecksum();
iPacket.setParent(ethPacketIn);
- ethPacketIn.setDestinationMACAddress(externalPeerRouterMac);
+ ethPacketIn.setSourceMACAddress(DEFAULT_GATEWAY_MAC);
+ ethPacketIn.setDestinationMACAddress(externalPeerRouter.externalPeerRouterMac());
ethPacketIn.setPayload(iPacket);
+
+ if (!externalPeerRouter.externalPeerRouterVlanId().equals(VlanId.NONE)) {
+ ethPacketIn.setVlanID(externalPeerRouter.externalPeerRouterVlanId().toShort());
+ }
+
ethPacketIn.resetChecksum();
OpenstackNode srcNode = osNodeService.node(srcDevice);
@@ -490,11 +507,11 @@
throw new IllegalStateException(error);
}
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setOutput(srcNode.uplinkPortNum()).build();
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
packetService.emit(new DefaultOutboundPacket(
srcDevice,
- treatment,
+ tBuilder.setOutput(srcNode.uplinkPortNum()).build(),
ByteBuffer.wrap(ethPacketIn.serialize())));
}