[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,
diff --git a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/Constants.java b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/Constants.java
index b4074f7..8bb75a1 100644
--- a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/Constants.java
+++ b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/Constants.java
@@ -26,6 +26,7 @@
public static final String INTEGRATION_BRIDGE = "br-int";
public static final String ROUTER_BRIDGE = "br-router";
public static final String DEFAULT_TUNNEL = "vxlan";
+ public static final String VLAN = "vlan";
public static final String PATCH_INTG_BRIDGE = "patch-intg";
public static final String PATCH_ROUT_BRIDGE = "patch-rout";
diff --git a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeManager.java b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeManager.java
index 4f3e5e7..bea3a41 100644
--- a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeManager.java
+++ b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeManager.java
@@ -297,7 +297,7 @@
process(new OpenstackNodeEvent(COMPLETE, node));
switch (node.type()) {
case COMPUTE:
- selectGroupHandler.createGatewayGroup(node.intBridge(), gatewayNodes());
+ selectGroupHandler.createGatewayGroup(node, gatewayNodes());
break;
case GATEWAY:
updateGatewayGroup(node, true);
@@ -386,12 +386,15 @@
}
@Override
- public synchronized GroupId gatewayGroupId(DeviceId srcDeviceId) {
- GroupKey groupKey = selectGroupHandler.getGroupKey(srcDeviceId);
+ public synchronized GroupId gatewayGroupId(DeviceId srcDeviceId, NetworkMode networkMode) {
+ GroupKey groupKey = selectGroupHandler.groupKey(srcDeviceId, networkMode);
Group group = groupService.getGroup(srcDeviceId, groupKey);
+
if (group == null) {
log.info("Created gateway group for {}", srcDeviceId);
- return selectGroupHandler.createGatewayGroup(srcDeviceId, gatewayNodes());
+ selectGroupHandler.createGatewayGroup(nodeByDeviceId(srcDeviceId), gatewayNodes());
+
+ return groupService.getGroup(srcDeviceId, selectGroupHandler.groupKey(srcDeviceId, networkMode)).id();
} else {
return group.id();
}
@@ -425,13 +428,26 @@
.stream()
.map(Versioned::value)
.filter(node -> node.type().equals(NodeType.COMPUTE))
+ .filter(node -> node.dataIp().isPresent())
.filter(node -> node.state().equals(COMPLETE))
- .forEach(node -> {
- selectGroupHandler.updateGatewayGroupBuckets(node.intBridge(),
- ImmutableList.of(gatewayNode),
- isInsert);
- log.trace("Updated gateway group on {}", node.intBridge());
+ .forEach(computeNode -> {
+ selectGroupHandler.updateGatewayGroupBuckets(computeNode,
+ ImmutableList.of(gatewayNode), NetworkMode.VXLAN, isInsert);
+ log.trace("Updated gateway group on {} for vxlan mode", computeNode.intBridge());
});
+
+ nodeStore.values()
+ .stream()
+ .map(Versioned::value)
+ .filter(node -> node.type().equals(NodeType.COMPUTE))
+ .filter(node -> node.vlanPort().isPresent())
+ .filter(node -> node.state().equals(COMPLETE))
+ .forEach(computeNode -> {
+ selectGroupHandler.updateGatewayGroupBuckets(computeNode,
+ ImmutableList.of(gatewayNode), NetworkMode.VLAN, isInsert);
+ log.trace("Updated gateway group on {} for vlan mode", computeNode.intBridge());
+ });
+
}
private void initNode(OpenstackNode node) {
diff --git a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeService.java b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeService.java
index 7362893..9600280 100644
--- a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeService.java
+++ b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeService.java
@@ -39,6 +39,14 @@
GATEWAY
}
+ enum NetworkMode {
+ /**
+ * VxLAN or VLAN mode.
+ */
+ VXLAN,
+ VLAN
+ }
+
/**
* Adds or updates a new node to the service.
*
@@ -150,9 +158,10 @@
* If the group does not exist in the supplied source device, creates one.
*
* @param srcDeviceId source device id
- * @return The group id
+ * @param networkMode network mode
+ * @return group id
*/
- GroupId gatewayGroupId(DeviceId srcDeviceId);
+ GroupId gatewayGroupId(DeviceId srcDeviceId, NetworkMode networkMode);
/**
* Returns the list of gateway node information with the given device identifier.
diff --git a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/SelectGroupHandler.java b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/SelectGroupHandler.java
index df963db..5f8e065 100644
--- a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/SelectGroupHandler.java
+++ b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/SelectGroupHandler.java
@@ -18,8 +18,10 @@
import com.google.common.collect.Lists;
import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.GroupId;
+import org.onosproject.openstacknode.OpenstackNodeService.NetworkMode;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
@@ -47,7 +49,9 @@
import java.util.List;
+import static org.onosproject.net.AnnotationKeys.PORT_MAC;
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
+import static org.onosproject.openstacknode.Constants.*;
import static org.onosproject.net.group.DefaultGroupBucket.createSelectGroupBucket;
/**
@@ -57,7 +61,7 @@
private final Logger log = LoggerFactory.getLogger(getClass());
private static final String TUNNEL_DESTINATION = "tunnelDst";
- private static final String PORTNAME_PREFIX_TUNNEL = "vxlan";
+ private static final String ERR_UNSUPPORTED_NET_TYPE = "Unsupported network type";
private final GroupService groupService;
private final DeviceService deviceService;
@@ -83,81 +87,139 @@
/**
* Creates select type group description according to given deviceId.
*
- * @param srcDeviceId target device id for group description
+ * @param computeNode target device id for group description
* @param gatewayNodeList gateway node list for bucket action
- * @return created select type group description
*/
- public GroupId createGatewayGroup(DeviceId srcDeviceId, List<OpenstackNode> gatewayNodeList) {
- List<GroupBucket> bucketList = generateBucketsForSelectGroup(srcDeviceId, gatewayNodeList);
- GroupId groupId = getGroupId(srcDeviceId);
- GroupDescription groupDescription = new DefaultGroupDescription(
- srcDeviceId,
- GroupDescription.Type.SELECT,
- new GroupBuckets(bucketList),
- getGroupKey(srcDeviceId),
- groupId.id(),
- appId);
+ public void createGatewayGroup(OpenstackNode computeNode, List<OpenstackNode> gatewayNodeList) {
+ List<GroupBucket> bucketList;
+ GroupId groupId;
- groupService.addGroup(groupDescription);
- return groupId;
+ if (computeNode.dataIp().isPresent()) {
+ bucketList = generateBucketsForSelectGroup(computeNode, gatewayNodeList, NetworkMode.VXLAN);
+ groupId = groupId(computeNode.intBridge(), NetworkMode.VXLAN);
+
+ GroupDescription groupDescription = new DefaultGroupDescription(
+ computeNode.intBridge(),
+ GroupDescription.Type.SELECT,
+ new GroupBuckets(bucketList),
+ groupKey(computeNode.intBridge(), NetworkMode.VXLAN),
+ groupId.id(),
+ appId);
+
+ groupService.addGroup(groupDescription);
+ }
+
+ if (computeNode.vlanPort().isPresent()) {
+ bucketList = generateBucketsForSelectGroup(computeNode, gatewayNodeList, NetworkMode.VLAN);
+ groupId = groupId(computeNode.intBridge(), NetworkMode.VLAN);
+
+ GroupDescription groupDescription = new DefaultGroupDescription(
+ computeNode.intBridge(),
+ GroupDescription.Type.SELECT,
+ new GroupBuckets(bucketList),
+ groupKey(computeNode.intBridge(), NetworkMode.VLAN),
+ groupId.id(),
+ appId);
+
+ groupService.addGroup(groupDescription);
+ }
}
/**
- * Returns unique group key with supplied source device ID as a hash.
- *
+ * Returns unique group key with supplied source device ID and network mode as a hash.
* @param srcDeviceId source device id
+ * @param networkMode network mode
* @return group key
*/
- public GroupKey getGroupKey(DeviceId srcDeviceId) {
- return new DefaultGroupKey(srcDeviceId.toString().getBytes());
+ public GroupKey groupKey(DeviceId srcDeviceId, NetworkMode networkMode) {
+ if (networkMode.equals(NetworkMode.VXLAN)) {
+ return new DefaultGroupKey(srcDeviceId.toString().concat(DEFAULT_TUNNEL).getBytes());
+ } else {
+ return new DefaultGroupKey(srcDeviceId.toString().concat(VLAN).getBytes());
+ }
}
- private GroupId getGroupId(DeviceId srcDeviceId) {
- return new GroupId(srcDeviceId.toString().hashCode());
+ private GroupId groupId(DeviceId srcDeviceId, NetworkMode networkMode) {
+ if (networkMode.equals(NetworkMode.VXLAN)) {
+ return new GroupId(srcDeviceId.toString().concat(DEFAULT_TUNNEL).hashCode());
+ } else {
+ return new GroupId(srcDeviceId.toString().concat(VLAN).hashCode());
+ }
}
+
/**
* Updates groupBuckets in select type group.
*
- * @param deviceId target device id to update the group
+ * @param computeNode compute node
* @param gatewayNodeList updated gateway node list for bucket action
+ * @param networkMode network mode
* @param isInsert update type(add or remove)
*/
- public void updateGatewayGroupBuckets(DeviceId deviceId,
+ public void updateGatewayGroupBuckets(OpenstackNode computeNode,
List<OpenstackNode> gatewayNodeList,
+ NetworkMode networkMode,
boolean isInsert) {
- List<GroupBucket> bucketList = generateBucketsForSelectGroup(deviceId, gatewayNodeList);
- GroupKey groupKey = getGroupKey(deviceId);
- if (groupService.getGroup(deviceId, groupKey) == null) {
- log.error("There's no group in compute node {}", deviceId);
+ List<GroupBucket> bucketList = generateBucketsForSelectGroup(computeNode, gatewayNodeList, networkMode);
+ GroupKey groupKey = groupKey(computeNode.intBridge(), networkMode);
+ if (groupService.getGroup(computeNode.intBridge(), groupKey) == null) {
+ log.error("There's no group in compute node {}", computeNode.intBridge());
return;
}
if (isInsert) {
groupService.addBucketsToGroup(
- deviceId,
+ computeNode.intBridge(),
groupKey,
new GroupBuckets(bucketList),
groupKey, appId);
} else {
groupService.removeBucketsFromGroup(
- deviceId,
+ computeNode.intBridge(),
groupKey,
new GroupBuckets(bucketList),
groupKey, appId);
}
}
- private List<GroupBucket> generateBucketsForSelectGroup(DeviceId deviceId, List<OpenstackNode> gatewayNodeList) {
+
+
+ private List<GroupBucket> generateBucketsForSelectGroup(OpenstackNode computeNode,
+ List<OpenstackNode> gatewayNodeList,
+ NetworkMode networkMode) {
List<GroupBucket> bucketList = Lists.newArrayList();
- gatewayNodeList.forEach(node -> {
- TrafficTreatment tBuilder = DefaultTrafficTreatment.builder()
- .extension(buildNiciraExtenstion(deviceId, node.dataIp().get().getIp4Address()), deviceId)
- .setOutput(getTunnelPort(deviceId))
- .build();
- bucketList.add(createSelectGroupBucket(tBuilder));
- });
- return bucketList;
+
+ switch (networkMode) {
+ case VXLAN:
+ gatewayNodeList.stream()
+ .filter(node -> node.dataIp().isPresent())
+ .forEach(node -> {
+ TrafficTreatment tBuilder = DefaultTrafficTreatment.builder()
+ .extension(buildNiciraExtenstion(computeNode.intBridge(),
+ node.dataIp().get().getIp4Address()),
+ computeNode.intBridge())
+ .setOutput(getTunnelPort(computeNode.intBridge()))
+ .build();
+ bucketList.add(createSelectGroupBucket(tBuilder));
+ });
+ return bucketList;
+ case VLAN:
+ gatewayNodeList.stream()
+ .filter(node -> node.vlanPort().isPresent())
+ .forEach(node -> {
+ TrafficTreatment tBuilder = DefaultTrafficTreatment.builder()
+ .setEthDst(MacAddress.valueOf(vlanPortMac(node)))
+ .setOutput(vlanPortNum(computeNode))
+ .build();
+ bucketList.add(createSelectGroupBucket(tBuilder));
+ });
+ return bucketList;
+ default:
+ final String error = String.format(
+ ERR_UNSUPPORTED_NET_TYPE + "%s",
+ networkMode.toString());
+ throw new IllegalStateException(error);
+ }
}
/**
@@ -193,7 +255,7 @@
*/
private PortNumber getTunnelPort(DeviceId deviceId) {
Port port = deviceService.getPorts(deviceId).stream()
- .filter(p -> p.annotations().value(PORT_NAME).equals(PORTNAME_PREFIX_TUNNEL))
+ .filter(p -> p.annotations().value(PORT_NAME).equals(DEFAULT_TUNNEL))
.findAny().orElse(null);
if (port == null) {
@@ -201,6 +263,18 @@
return null;
}
return port.number();
+ }
+ private PortNumber vlanPortNum(OpenstackNode node) {
+ return deviceService.getPorts(node.intBridge()).stream()
+ .filter(p -> p.annotations().value(PORT_NAME).equals(node.vlanPort().get()) &&
+ p.isEnabled())
+ .map(Port::number).findFirst().get();
+
+ }
+ private String vlanPortMac(OpenstackNode node) {
+ return deviceService.getPorts(node.intBridge()).stream()
+ .filter(p -> p.annotations().value(PORT_NAME).equals(node.vlanPort().get()) && p.isEnabled())
+ .findFirst().get().annotations().value(PORT_MAC);
}
}