[ONOS-6168, ONOS-6436] Implement multiple gateway nodes support for VLAN mode and implement VLAN based Logical Routing
Change-Id: Ifd1c26375abdf84603f28184e9cb9ad6c88648dd
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
index f3e8363..90f32c3 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingFloatingIpHandler.java
@@ -24,6 +24,7 @@
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;
@@ -49,6 +50,7 @@
import org.onosproject.openstacknode.OpenstackNodeService;
import org.openstack4j.model.network.NetFloatingIP;
import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.NetworkType;
import org.openstack4j.model.network.Port;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -72,6 +74,7 @@
private final Logger log = LoggerFactory.getLogger(getClass());
private static final String ERR_FLOW = "Failed set flows for floating IP %s: ";
+ private static final String ERR_UNSUPPORTED_NET_TYPE = "Unsupported network type";
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@@ -167,25 +170,39 @@
.build();
osNodeService.gatewayDeviceIds().forEach(gnodeId -> {
- TrafficTreatment externalTreatment = DefaultTrafficTreatment.builder()
+ TrafficTreatment.Builder externalBuilder = DefaultTrafficTreatment.builder()
.setEthSrc(Constants.DEFAULT_GATEWAY_MAC)
.setEthDst(instPort.macAddress())
- .setIpDst(instPort.ipAddress().getIp4Address())
- .setTunnelId(Long.valueOf(osNet.getProviderSegID()))
- .extension(buildExtension(
- deviceService,
- gnodeId,
- dataIp.get().getIp4Address()),
- gnodeId)
- .setOutput(osNodeService.tunnelPort(gnodeId).get())
- .build();
+ .setIpDst(instPort.ipAddress().getIp4Address());
+
+ switch (osNet.getNetworkType()) {
+ case VXLAN:
+ externalBuilder.setTunnelId(Long.valueOf(osNet.getProviderSegID()))
+ .extension(buildExtension(
+ deviceService,
+ gnodeId,
+ dataIp.get().getIp4Address()),
+ gnodeId)
+ .setOutput(osNodeService.tunnelPort(gnodeId).get());
+ break;
+ case VLAN:
+ externalBuilder.pushVlan()
+ .setVlanId(VlanId.vlanId(osNet.getProviderSegID()))
+ .setOutput(osNodeService.vlanPort(gnodeId).get());
+ break;
+ default:
+ final String error = String.format(
+ ERR_UNSUPPORTED_NET_TYPE + "%s",
+ osNet.getNetworkType().toString());
+ throw new IllegalStateException(error);
+ }
RulePopulatorUtil.setRule(
flowObjectiveService,
appId,
gnodeId,
externalSelector,
- externalTreatment,
+ externalBuilder.build(),
ForwardingObjective.Flag.VERSATILE,
PRIORITY_FLOATING_EXTERNAL,
install);
@@ -197,25 +214,39 @@
.matchInPort(osNodeService.tunnelPort(gnodeId).get())
.build();
- TrafficTreatment internalTreatment = DefaultTrafficTreatment.builder()
+ TrafficTreatment.Builder internalBuilder = DefaultTrafficTreatment.builder()
.setEthSrc(Constants.DEFAULT_GATEWAY_MAC)
.setEthDst(instPort.macAddress())
- .setIpDst(instPort.ipAddress().getIp4Address())
- .setTunnelId(Long.valueOf(osNet.getProviderSegID()))
- .extension(buildExtension(
- deviceService,
- gnodeId,
- dataIp.get().getIp4Address()),
- gnodeId)
- .setOutput(PortNumber.IN_PORT)
- .build();
+ .setIpDst(instPort.ipAddress().getIp4Address());
+
+ switch (osNet.getNetworkType()) {
+ case VXLAN:
+ internalBuilder.setTunnelId(Long.valueOf(osNet.getProviderSegID()))
+ .extension(buildExtension(
+ deviceService,
+ gnodeId,
+ dataIp.get().getIp4Address()),
+ gnodeId)
+ .setOutput(PortNumber.IN_PORT);
+ break;
+ case VLAN:
+ internalBuilder.pushVlan()
+ .setVlanId(VlanId.vlanId(osNet.getProviderSegID()))
+ .setOutput(PortNumber.IN_PORT);
+ break;
+ default:
+ final String error = String.format(
+ ERR_UNSUPPORTED_NET_TYPE + "%s",
+ osNet.getNetworkType().toString());
+ throw new IllegalStateException(error);
+ }
RulePopulatorUtil.setRule(
flowObjectiveService,
appId,
gnodeId,
internalSelector,
- internalTreatment,
+ internalBuilder.build(),
ForwardingObjective.Flag.VERSATILE,
PRIORITY_FLOATING_INTERNAL,
install);
@@ -225,26 +256,41 @@
private void setUpstreamRules(NetFloatingIP floatingIp, Network osNet,
InstancePort instPort, boolean install) {
IpAddress floating = IpAddress.valueOf(floatingIp.getFloatingIpAddress());
- TrafficSelector selector = DefaultTrafficSelector.builder()
+
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
- .matchTunnelId(Long.valueOf(osNet.getProviderSegID()))
- .matchIPSrc(instPort.ipAddress().toIpPrefix())
- .build();
+ .matchIPSrc(instPort.ipAddress().toIpPrefix());
+
+ switch (osNet.getNetworkType()) {
+ case VXLAN:
+ sBuilder.matchTunnelId(Long.valueOf(osNet.getProviderSegID()));
+ break;
+ case VLAN:
+ sBuilder.matchVlanId(VlanId.vlanId(osNet.getProviderSegID()));
+ break;
+ default:
+ final String error = String.format(
+ ERR_UNSUPPORTED_NET_TYPE + "%s",
+ osNet.getNetworkType().toString());
+ throw new IllegalStateException(error);
+ }
osNodeService.gatewayDeviceIds().forEach(gnodeId -> {
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
.setIpSrc(floating.getIp4Address())
.setEthSrc(Constants.DEFAULT_GATEWAY_MAC)
- .setEthDst(Constants.DEFAULT_EXTERNAL_ROUTER_MAC)
- .setOutput(osNodeService.externalPort(gnodeId).get())
- .build();
+ .setEthDst(Constants.DEFAULT_EXTERNAL_ROUTER_MAC);
+
+ if (osNet.getNetworkType().equals(NetworkType.VLAN)) {
+ tBuilder.popVlan();
+ }
RulePopulatorUtil.setRule(
flowObjectiveService,
appId,
gnodeId,
- selector,
- treatment,
+ sBuilder.build(),
+ tBuilder.setOutput(osNodeService.externalPort(gnodeId).get()).build(),
ForwardingObjective.Flag.VERSATILE,
PRIORITY_FLOATING_EXTERNAL,
install);
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
index c5d5f29..b004ee7 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingHandler.java
@@ -26,6 +26,8 @@
import org.onlab.packet.IPv4;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;
@@ -34,6 +36,7 @@
import org.onosproject.core.GroupId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
@@ -49,8 +52,11 @@
import org.onosproject.openstacknode.OpenstackNodeEvent;
import org.onosproject.openstacknode.OpenstackNodeListener;
import org.onosproject.openstacknode.OpenstackNodeService;
+import org.onosproject.openstacknode.OpenstackNodeService.NetworkMode;
+
import org.openstack4j.model.network.ExternalGateway;
import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.NetworkType;
import org.openstack4j.model.network.Router;
import org.openstack4j.model.network.RouterInterface;
import org.openstack4j.model.network.Subnet;
@@ -64,6 +70,8 @@
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.AnnotationKeys.PORT_MAC;
+import static org.onosproject.net.AnnotationKeys.PORT_NAME;
import static org.onosproject.openstacknetworking.api.Constants.*;
import static org.onosproject.openstacknode.OpenstackNodeService.NodeType.COMPUTE;
@@ -78,6 +86,7 @@
private static final String MSG_ENABLED = "Enabled ";
private static final String MSG_DISABLED = "Disabled ";
private static final String ERR_SET_FLOWS = "Failed to set flows for router %s:";
+ private static final String ERR_UNSUPPORTED_NET_TYPE = "Unsupported network type";
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@@ -100,6 +109,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected OpenstackRouterService osRouterService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
private final ExecutorService eventExecutor = newSingleThreadScheduledExecutor(
groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
private final OpenstackNodeListener osNodeListener = new InternalNodeEventListener();
@@ -151,7 +163,6 @@
osRouterIface.getSubnetId());
throw new IllegalStateException(error);
}
-
setInternalRoutes(osRouter, osSubnet, true);
setGatewayIcmp(osSubnet, true);
ExternalGateway exGateway = osRouter.getExternalGatewayInfo();
@@ -189,20 +200,18 @@
osNodeService.completeNodes().stream()
.filter(osNode -> osNode.type() == COMPUTE)
.forEach(osNode -> {
- setRulesToGateway(
- osNode.intBridge(),
- osNodeService.gatewayGroupId(osNode.intBridge()),
- Long.valueOf(osNet.getProviderSegID()),
- IpPrefix.valueOf(osSubnet.getCidr()),
- install);
+ setRulesToGateway(osNode.intBridge(), osNet.getProviderSegID(),
+ IpPrefix.valueOf(osSubnet.getCidr()), osNet.getNetworkType(),
+ install);
});
// take the first outgoing packet to controller for source NAT
osNodeService.gatewayDeviceIds()
.forEach(gwDeviceId -> setRulesToController(
gwDeviceId,
- Long.valueOf(osNet.getProviderSegID()),
+ osNet.getProviderSegID(),
IpPrefix.valueOf(osSubnet.getCidr()),
+ osNet.getNetworkType(),
install));
final String updateStr = install ? MSG_ENABLED : MSG_DISABLED;
@@ -217,14 +226,37 @@
// take ICMP request to a subnet gateway through gateway node group
Network network = osNetworkService.network(osSubnet.getNetworkId());
- osNodeService.completeNodes().stream()
- .filter(osNode -> osNode.type() == COMPUTE)
- .forEach(osNode -> setRulesToGatewayWithDstIp(
- osNode.intBridge(),
- osNodeService.gatewayGroupId(osNode.intBridge()),
- Long.valueOf(network.getProviderSegID()),
- IpAddress.valueOf(osSubnet.getGateway()),
- install));
+ switch (network.getNetworkType()) {
+ case VXLAN:
+ osNodeService.completeNodes().stream()
+ .filter(osNode -> osNode.type() == COMPUTE)
+ .filter(osNode -> osNode.dataIp().isPresent())
+ .forEach(osNode -> setRulesToGatewayWithDstIp(
+ osNode.intBridge(),
+ osNodeService.gatewayGroupId(osNode.intBridge(), NetworkMode.VXLAN),
+ network.getProviderSegID(),
+ IpAddress.valueOf(osSubnet.getGateway()),
+ NetworkMode.VXLAN,
+ install));
+ break;
+ case VLAN:
+ osNodeService.completeNodes().stream()
+ .filter(osNode -> osNode.type() == COMPUTE)
+ .filter(osNode -> osNode.vlanPort().isPresent())
+ .forEach(osNode -> setRulesToGatewayWithDstIp(
+ osNode.intBridge(),
+ osNodeService.gatewayGroupId(osNode.intBridge(), NetworkMode.VLAN),
+ network.getProviderSegID(),
+ IpAddress.valueOf(osSubnet.getGateway()),
+ NetworkMode.VLAN,
+ install));
+ break;
+ default:
+ final String error = String.format(
+ ERR_UNSUPPORTED_NET_TYPE + "%s",
+ network.getNetworkType().toString());
+ throw new IllegalStateException(error);
+ }
IpAddress gatewayIp = IpAddress.valueOf(osSubnet.getGateway());
osNodeService.gatewayDeviceIds()
@@ -239,8 +271,9 @@
}
private void setInternalRoutes(Router osRouter, Subnet updatedSubnet, boolean install) {
+ Network updatedNetwork = osNetworkService.network(updatedSubnet.getNetworkId());
Set<Subnet> routableSubnets = routableSubnets(osRouter, updatedSubnet.getId());
- Long updatedVni = getVni(updatedSubnet);
+ String updatedSegmendId = getSegmentId(updatedSubnet);
// installs rule from/to my subnet intentionally to fix ICMP failure
// to my subnet gateway if no external gateway added to the router
@@ -249,33 +282,37 @@
.forEach(osNode -> {
setInternalRouterRules(
osNode.intBridge(),
- updatedVni,
- updatedVni,
+ updatedSegmendId,
+ updatedSegmendId,
IpPrefix.valueOf(updatedSubnet.getCidr()),
IpPrefix.valueOf(updatedSubnet.getCidr()),
+ updatedNetwork.getNetworkType(),
install
);
routableSubnets.forEach(subnet -> {
setInternalRouterRules(
osNode.intBridge(),
- updatedVni,
- getVni(subnet),
+ updatedSegmendId,
+ getSegmentId(subnet),
IpPrefix.valueOf(updatedSubnet.getCidr()),
IpPrefix.valueOf(subnet.getCidr()),
+ updatedNetwork.getNetworkType(),
install
);
setInternalRouterRules(
osNode.intBridge(),
- getVni(subnet),
- updatedVni,
+ getSegmentId(subnet),
+ updatedSegmendId,
IpPrefix.valueOf(subnet.getCidr()),
IpPrefix.valueOf(updatedSubnet.getCidr()),
+ updatedNetwork.getNetworkType(),
install
);
});
});
+
final String updateStr = install ? MSG_ENABLED : MSG_DISABLED;
routableSubnets.forEach(subnet -> log.debug(
updateStr + "route between subnet:{} and subnet:{}",
@@ -292,9 +329,8 @@
return ImmutableSet.copyOf(osSubnets);
}
- private Long getVni(Subnet osSubnet) {
- return Long.parseLong(osNetworkService.network(
- osSubnet.getNetworkId()).getProviderSegID());
+ private String getSegmentId(Subnet osSubnet) {
+ return osNetworkService.network(osSubnet.getNetworkId()).getProviderSegID();
}
private void setGatewayIcmpRule(IpAddress gatewayIp, DeviceId deviceId, boolean install) {
@@ -319,61 +355,136 @@
install);
}
- private void setInternalRouterRules(DeviceId deviceId, Long srcVni, Long dstVni,
- IpPrefix srcSubnet, IpPrefix dstSubnet, boolean install) {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchTunnelId(srcVni)
- .matchIPSrc(srcSubnet)
- .matchIPDst(dstSubnet)
- .build();
+ private void setInternalRouterRules(DeviceId deviceId, String srcSegmentId, String dstSegmentId,
+ IpPrefix srcSubnet, IpPrefix dstSubnet,
+ NetworkType networkType, boolean install) {
+ TrafficSelector selector;
+ TrafficTreatment treatment;
+ switch (networkType) {
+ case VXLAN:
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchTunnelId(Long.parseLong(srcSegmentId))
+ .matchIPSrc(srcSubnet)
+ .matchIPDst(dstSubnet)
+ .build();
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setTunnelId(dstVni)
- .build();
+ treatment = DefaultTrafficTreatment.builder()
+ .setTunnelId(Long.parseLong(dstSegmentId))
+ .build();
- RulePopulatorUtil.setRule(
- flowObjectiveService,
- appId,
- deviceId,
- selector,
- treatment,
- ForwardingObjective.Flag.SPECIFIC,
- PRIORITY_INTERNAL_ROUTING_RULE,
- install);
+ RulePopulatorUtil.setRule(
+ flowObjectiveService,
+ appId,
+ deviceId,
+ selector,
+ treatment,
+ ForwardingObjective.Flag.SPECIFIC,
+ PRIORITY_INTERNAL_ROUTING_RULE,
+ install);
- selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchTunnelId(dstVni)
- .matchIPSrc(srcSubnet)
- .matchIPDst(dstSubnet)
- .build();
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchTunnelId(Long.parseLong(dstSegmentId))
+ .matchIPSrc(srcSubnet)
+ .matchIPDst(dstSubnet)
+ .build();
- treatment = DefaultTrafficTreatment.builder()
- .setTunnelId(dstVni)
- .build();
+ treatment = DefaultTrafficTreatment.builder()
+ .setTunnelId(Long.parseLong(dstSegmentId))
+ .build();
- RulePopulatorUtil.setRule(
- flowObjectiveService,
- appId,
- deviceId,
- selector,
- treatment,
- ForwardingObjective.Flag.SPECIFIC,
- PRIORITY_INTERNAL_ROUTING_RULE,
- install);
+ RulePopulatorUtil.setRule(
+ flowObjectiveService,
+ appId,
+ deviceId,
+ selector,
+ treatment,
+ ForwardingObjective.Flag.SPECIFIC,
+ PRIORITY_INTERNAL_ROUTING_RULE,
+ install);
+ break;
+ case VLAN:
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchVlanId(VlanId.vlanId(srcSegmentId))
+ .matchIPSrc(srcSubnet)
+ .matchIPDst(dstSubnet)
+ .build();
+
+ treatment = DefaultTrafficTreatment.builder()
+ .setVlanId(VlanId.vlanId(dstSegmentId))
+ .build();
+
+ RulePopulatorUtil.setRule(
+ flowObjectiveService,
+ appId,
+ deviceId,
+ selector,
+ treatment,
+ ForwardingObjective.Flag.SPECIFIC,
+ PRIORITY_INTERNAL_ROUTING_RULE,
+ install);
+
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchVlanId(VlanId.vlanId(dstSegmentId))
+ .matchIPSrc(srcSubnet)
+ .matchIPDst(dstSubnet)
+ .build();
+
+ treatment = DefaultTrafficTreatment.builder()
+ .setVlanId(VlanId.vlanId(dstSegmentId))
+ .build();
+
+ RulePopulatorUtil.setRule(
+ flowObjectiveService,
+ appId,
+ deviceId,
+ selector,
+ treatment,
+ ForwardingObjective.Flag.SPECIFIC,
+ PRIORITY_INTERNAL_ROUTING_RULE,
+ install);
+ break;
+ default:
+ final String error = String.format(
+ ERR_UNSUPPORTED_NET_TYPE + "%s",
+ networkType.toString());
+ throw new IllegalStateException(error);
+ }
+
}
- private void setRulesToGateway(DeviceId deviceId, GroupId groupId, Long vni,
- IpPrefix srcSubnet, boolean install) {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchTunnelId(vni)
- .matchIPSrc(srcSubnet)
- .matchEthDst(Constants.DEFAULT_GATEWAY_MAC)
- .build();
+ private void setRulesToGateway(DeviceId deviceId, String segmentId, IpPrefix srcSubnet,
+ NetworkType networkType, boolean install) {
+ TrafficTreatment treatment;
+ GroupId groupId;
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPSrc(srcSubnet)
+ .matchEthDst(Constants.DEFAULT_GATEWAY_MAC);
+
+ switch (networkType) {
+ case VXLAN:
+ sBuilder.matchTunnelId(Long.parseLong(segmentId));
+
+ groupId = osNodeService.gatewayGroupId(deviceId, NetworkMode.VXLAN);
+ break;
+ case VLAN:
+ sBuilder.matchVlanId(VlanId.vlanId(segmentId));
+
+ groupId = osNodeService.gatewayGroupId(deviceId, NetworkMode.VLAN);
+ break;
+ default:
+ final String error = String.format(
+ ERR_UNSUPPORTED_NET_TYPE + "%s",
+ networkType.toString());
+ throw new IllegalStateException(error);
+ }
+
+ treatment = DefaultTrafficTreatment.builder()
.group(groupId)
.build();
@@ -381,43 +492,78 @@
flowObjectiveService,
appId,
deviceId,
- selector,
+ sBuilder.build(),
treatment,
ForwardingObjective.Flag.SPECIFIC,
PRIORITY_EXTERNAL_ROUTING_RULE,
install);
}
- private void setRulesToController(DeviceId deviceId, Long vni, IpPrefix srcSubnet, boolean install) {
- TrafficSelector selector = DefaultTrafficSelector.builder()
+ private void setRulesToController(DeviceId deviceId, String segmentId, IpPrefix srcSubnet,
+ NetworkType networkType, boolean install) {
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
- .matchTunnelId(vni)
- .matchIPSrc(srcSubnet)
- .matchEthDst(Constants.DEFAULT_GATEWAY_MAC)
- .build();
+ .matchIPSrc(srcSubnet);
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setOutput(PortNumber.CONTROLLER)
- .build();
+ switch (networkType) {
+ case VXLAN:
+ sBuilder.matchTunnelId(Long.parseLong(segmentId))
+ .matchEthDst(Constants.DEFAULT_GATEWAY_MAC);
+ break;
+ case VLAN:
+ sBuilder.matchVlanId(VlanId.vlanId(segmentId))
+ .matchEthDst(MacAddress.valueOf(vlanPortMac(deviceId)));
+ break;
+ default:
+ final String error = String.format(
+ ERR_UNSUPPORTED_NET_TYPE + "%s",
+ networkType.toString());
+ throw new IllegalStateException(error);
+ }
+
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
+ .setEthDst(Constants.DEFAULT_GATEWAY_MAC);
+
+ if (networkType.equals(NetworkType.VLAN)) {
+ tBuilder.popVlan();
+ }
+
+ tBuilder.setOutput(PortNumber.CONTROLLER);
RulePopulatorUtil.setRule(
flowObjectiveService,
appId,
deviceId,
- selector,
- treatment,
+ sBuilder.build(),
+ tBuilder.build(),
ForwardingObjective.Flag.VERSATILE,
PRIORITY_EXTERNAL_ROUTING_RULE,
install);
}
- private void setRulesToGatewayWithDstIp(DeviceId deviceId, GroupId groupId, Long vni,
- IpAddress dstIp, boolean install) {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchTunnelId(vni)
- .matchIPDst(dstIp.toIpPrefix())
- .build();
+ private String vlanPortMac(DeviceId deviceId) {
+ return deviceService.getPorts(deviceId).stream()
+ .filter(p -> p.annotations()
+ .value(PORT_NAME).equals(osNodeService.gatewayNode(deviceId).vlanPort().get()) && p.isEnabled())
+ .findFirst().get().annotations().value(PORT_MAC);
+ }
+
+ private void setRulesToGatewayWithDstIp(DeviceId deviceId, GroupId groupId, String segmentId,
+ IpAddress dstIp, NetworkMode networkMode, boolean install) {
+ TrafficSelector selector;
+ if (networkMode.equals(NetworkMode.VXLAN)) {
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchTunnelId(Long.valueOf(segmentId))
+ .matchIPDst(dstIp.toIpPrefix())
+ .build();
+ } else {
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchVlanId(VlanId.vlanId(segmentId))
+ .matchIPDst(dstIp.toIpPrefix())
+ .build();
+ }
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.group(groupId)
diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
index bd6eeb2..ab8f92c 100644
--- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
+++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingSnatHandler.java
@@ -27,6 +27,7 @@
import org.onlab.packet.TCP;
import org.onlab.packet.TpPort;
import org.onlab.packet.UDP;
+import org.onlab.packet.VlanId;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
@@ -57,6 +58,7 @@
import org.openstack4j.model.network.ExternalGateway;
import org.openstack4j.model.network.IP;
import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.NetworkType;
import org.openstack4j.model.network.Port;
import org.openstack4j.model.network.Router;
import org.openstack4j.model.network.RouterInterface;
@@ -81,6 +83,7 @@
private final Logger log = getLogger(getClass());
private static final String ERR_PACKETIN = "Failed to handle packet in: ";
+ private static final String ERR_UNSUPPORTED_NET_TYPE = "Unsupported network type";
private static final int TIME_OUT_SNAT_RULE = 120;
private static final long TIME_OUT_SNAT_PORT_MS = 120 * 1000;
private static final int TP_PORT_MINIMUM_NUM = 1024;
@@ -168,10 +171,6 @@
InboundPacket packetIn = context.inPacket();
int patPort = getPortNum();
- if (patPort == 0) {
- log.error("There's no unused port for PAT. Drop this packet");
- return;
- }
InstancePort srcInstPort = instancePortService.instancePort(eth.getSourceMAC());
if (srcInstPort == null) {
@@ -260,18 +259,20 @@
}
setDownstreamRules(srcInstPort,
- Long.parseLong(osNet.getProviderSegID()),
+ osNet.getProviderSegID(),
+ osNet.getNetworkType(),
externalIp,
patPort,
packetIn);
- setUpstreamRules(Long.parseLong(osNet.getProviderSegID()),
+ setUpstreamRules(osNet.getProviderSegID(),
+ osNet.getNetworkType(),
externalIp,
patPort,
packetIn);
}
- private void setDownstreamRules(InstancePort srcInstPort, Long srcVni,
+ private void setDownstreamRules(InstancePort srcInstPort, String segmentId, NetworkType networkType,
IpAddress externalIp, TpPort patPort,
InboundPacket packetIn) {
IPv4 iPacket = (IPv4) packetIn.parsed().getPayload();
@@ -284,10 +285,26 @@
.matchIPSrc(IpPrefix.valueOf(iPacket.getDestinationAddress(), 32));
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
- .setTunnelId(srcVni)
.setEthDst(packetIn.parsed().getSourceMAC())
.setIpDst(internalIp);
+ switch (networkType) {
+ case VXLAN:
+ tBuilder.setTunnelId(Long.parseLong(segmentId));
+ break;
+ case VLAN:
+ tBuilder.pushVlan()
+ .setVlanId(VlanId.vlanId(segmentId))
+ .setEthSrc(DEFAULT_GATEWAY_MAC);
+ break;
+ default:
+ final String error = String.format(
+ ERR_UNSUPPORTED_NET_TYPE + "%s",
+ networkType.toString());
+ throw new IllegalStateException(error);
+ }
+
+
switch (iPacket.getProtocol()) {
case IPv4.PROTOCOL_TCP:
TCP tcpPacket = (TCP) iPacket.getPayload();
@@ -309,11 +326,23 @@
DeviceId srcDeviceId = srcInstPort.deviceId();
TrafficTreatment.Builder tmpBuilder =
DefaultTrafficTreatment.builder(tBuilder.build());
- tmpBuilder.extension(RulePopulatorUtil.buildExtension(
- deviceService,
- deviceId,
- osNodeService.dataIp(srcDeviceId).get().getIp4Address()), deviceId)
- .setOutput(osNodeService.tunnelPort(deviceId).get());
+ switch (networkType) {
+ case VXLAN:
+ tmpBuilder.extension(RulePopulatorUtil.buildExtension(
+ deviceService,
+ deviceId,
+ osNodeService.dataIp(srcDeviceId).get().getIp4Address()), deviceId)
+ .setOutput(osNodeService.tunnelPort(deviceId).get());
+ break;
+ case VLAN:
+ tmpBuilder.setOutput(osNodeService.vlanPort(deviceId).get());
+ break;
+ default:
+ final String error = String.format(
+ ERR_UNSUPPORTED_NET_TYPE + "%s",
+ networkType.toString());
+ throw new IllegalStateException(error);
+ }
ForwardingObjective fo = DefaultForwardingObjective.builder()
.withSelector(sBuilder.build())
@@ -328,17 +357,33 @@
});
}
- private void setUpstreamRules(Long srcVni, IpAddress externalIp, TpPort patPort,
+ private void setUpstreamRules(String segmentId, NetworkType networkType, IpAddress externalIp, TpPort patPort,
InboundPacket packetIn) {
IPv4 iPacket = (IPv4) packetIn.parsed().getPayload();
- TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(iPacket.getProtocol())
- .matchTunnelId(srcVni)
.matchIPSrc(IpPrefix.valueOf(iPacket.getSourceAddress(), 32))
.matchIPDst(IpPrefix.valueOf(iPacket.getDestinationAddress(), 32));
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+
+ switch (networkType) {
+ case VXLAN:
+ sBuilder.matchTunnelId(Long.parseLong(segmentId));
+ break;
+ case VLAN:
+ sBuilder.matchVlanId(VlanId.vlanId(segmentId));
+ tBuilder.popVlan();
+ break;
+ default:
+ final String error = String.format(
+ ERR_UNSUPPORTED_NET_TYPE + "%s",
+ networkType.toString());
+ throw new IllegalStateException(error);
+ }
+
switch (iPacket.getProtocol()) {
case IPv4.PROTOCOL_TCP:
TCP tcpPacket = (TCP) iPacket.getPayload();
@@ -407,11 +452,11 @@
iPacket.setParent(ethPacketIn);
ethPacketIn.setDestinationMACAddress(DEFAULT_EXTERNAL_ROUTER_MAC);
ethPacketIn.setPayload(iPacket);
+ ethPacketIn.resetChecksum();
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setOutput(osNodeService.externalPort(srcDevice).get())
- .build();
- ethPacketIn.resetChecksum();
+ .setOutput(osNodeService.externalPort(srcDevice).get()).build();
+
packetService.emit(new DefaultOutboundPacket(
srcDevice,
treatment,