Revert "CORD-248 Provide host management network connectivity to a VM"
This reverts commit acbc8effe4f4687dd1c2a79c0ae1fa3edab747e5.
Change-Id: Ief4fc512d252d0143e5106e79e7f346d705a2e29
diff --git a/src/main/java/org/opencord/cordvtn/impl/CordVtnArpProxy.java b/src/main/java/org/opencord/cordvtn/impl/CordVtnArpProxy.java
index 1697f1a..9e8d313 100644
--- a/src/main/java/org/opencord/cordvtn/impl/CordVtnArpProxy.java
+++ b/src/main/java/org/opencord/cordvtn/impl/CordVtnArpProxy.java
@@ -28,8 +28,6 @@
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.PortNumber;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.xosclient.api.VtnService;
import org.opencord.cordvtn.api.CordVtnConfig;
@@ -52,7 +50,6 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.xosclient.api.VtnServiceApi.NetworkType.PRIVATE;
-import static org.onosproject.xosclient.api.VtnServiceApi.ServiceType.MANAGEMENT;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -65,9 +62,6 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PacketService packetService;
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CordVtnNodeManager nodeManager;
-
private final PacketProcessor packetProcessor = new InternalPacketProcessor();
private final Map<Ip4Address, MacAddress> gateways = Maps.newConcurrentMap();
@@ -138,26 +132,31 @@
/**
* Emits ARP reply with fake MAC address for a given ARP request.
- * It only handles requests for the registered gateway IPs and host IPs.
+ * It only handles requests for the registered service IPs, and the other
+ * requests can be handled by other ARP handlers like openstackSwitching or
+ * proxyArp, for example.
*
* @param context packet context
* @param ethPacket ethernet packet
*/
- private void processArpRequest(PacketContext context, Ethernet ethPacket) {
+ private void processArpPacket(PacketContext context, Ethernet ethPacket) {
ARP arpPacket = (ARP) ethPacket.getPayload();
+ if (arpPacket.getOpCode() != ARP.OP_REQUEST) {
+ return;
+ }
+
Ip4Address targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress());
MacAddress gatewayMac = gateways.get(targetIp);
- MacAddress replyMac = gatewayMac != null ? gatewayMac :
- getMacFromHostService(targetIp);
+ MacAddress replyMac = gatewayMac != null ? gatewayMac : getMacFromHostService(targetIp);
if (replyMac.equals(MacAddress.NONE)) {
- log.trace("Failed to find MAC for {}", targetIp);
- forwardManagementArpRequest(context, ethPacket);
+ log.debug("Failed to find MAC for {}", targetIp.toString());
+ context.block();
return;
}
- log.trace("Send ARP reply for {} with {}", targetIp, replyMac);
+ log.trace("Send ARP reply for {} with {}", targetIp.toString(), replyMac.toString());
Ethernet ethReply = ARP.buildArpReply(
targetIp,
replyMac,
@@ -175,62 +174,6 @@
context.block();
}
- private void processArpReply(PacketContext context, Ethernet ethPacket) {
- ARP arpPacket = (ARP) ethPacket.getPayload();
- Ip4Address targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress());
-
- DeviceId deviceId = context.inPacket().receivedFrom().deviceId();
- Host host = hostService.getHostsByIp(targetIp).stream()
- .filter(h -> h.location().deviceId().equals(deviceId))
- .findFirst()
- .orElse(null);
-
- if (host == null) {
- // do nothing for the unknown ARP reply
- log.trace("No host found for {} in {}", targetIp, deviceId);
- context.block();
- return;
- }
-
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setOutput(host.location().port())
- .build();
-
- packetService.emit(new DefaultOutboundPacket(
- deviceId,
- treatment,
- ByteBuffer.wrap(ethPacket.serialize())));
-
- context.block();
- }
-
- private void forwardManagementArpRequest(PacketContext context, Ethernet ethPacket) {
- DeviceId deviceId = context.inPacket().receivedFrom().deviceId();
- PortNumber hostMgmtPort = nodeManager.hostManagementPort(deviceId);
- Host host = hostService.getConnectedHosts(context.inPacket().receivedFrom())
- .stream()
- .findFirst().orElse(null);
-
- if (host == null ||
- !Instance.of(host).serviceType().equals(MANAGEMENT) ||
- hostMgmtPort == null) {
- context.block();
- return;
- }
-
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setOutput(hostMgmtPort)
- .build();
-
- packetService.emit(new DefaultOutboundPacket(
- context.inPacket().receivedFrom().deviceId(),
- treatment,
- ByteBuffer.wrap(ethPacket.serialize())));
-
- log.trace("Forward ARP request to management network");
- context.block();
- }
-
/**
* Emits gratuitous ARP when a gateway mac address has been changed.
*
@@ -240,7 +183,7 @@
private void sendGratuitousArp(IpAddress gatewayIp, Set<Instance> instances) {
MacAddress gatewayMac = gateways.get(gatewayIp.getIp4Address());
if (gatewayMac == null) {
- log.debug("Gateway {} is not registered to ARP proxy", gatewayIp);
+ log.debug("Gateway {} is not registered to ARP proxy", gatewayIp.toString());
return;
}
@@ -303,7 +246,7 @@
.orElse(null);
if (host != null) {
- log.trace("Found MAC from host service for {}", targetIp);
+ log.trace("Found MAC from host service for {}", targetIp.toString());
return host.mac();
} else {
return MacAddress.NONE;
@@ -321,18 +264,7 @@
if (ethPacket == null || ethPacket.getEtherType() != Ethernet.TYPE_ARP) {
return;
}
-
- ARP arpPacket = (ARP) ethPacket.getPayload();
- switch (arpPacket.getOpCode()) {
- case ARP.OP_REQUEST:
- processArpRequest(context, ethPacket);
- break;
- case ARP.OP_REPLY:
- processArpReply(context, ethPacket);
- break;
- default:
- break;
- }
+ processArpPacket(context, ethPacket);
}
}
diff --git a/src/main/java/org/opencord/cordvtn/impl/CordVtnNodeManager.java b/src/main/java/org/opencord/cordvtn/impl/CordVtnNodeManager.java
index c45fef3..df3d336 100644
--- a/src/main/java/org/opencord/cordvtn/impl/CordVtnNodeManager.java
+++ b/src/main/java/org/opencord/cordvtn/impl/CordVtnNodeManager.java
@@ -28,7 +28,6 @@
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;
-import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.behaviour.BridgeDescription;
import org.onosproject.net.behaviour.DefaultBridgeDescription;
import org.onosproject.net.behaviour.InterfaceConfig;
@@ -74,7 +73,6 @@
import java.util.List;
import java.util.Objects;
-import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
@@ -316,9 +314,12 @@
log.warn("Failed to get node for {}", deviceId);
return null;
}
+ Port port = deviceService.getPorts(deviceId).stream()
+ .filter(p -> portName(p).contains(node.dataIface()) &&
+ p.isEnabled())
+ .findFirst().orElse(null);
- Optional<PortNumber> port = getPortNumber(deviceId, node.dataIface());
- return port.isPresent() ? port.get() : null;
+ return port == null ? null : port.number();
}
/**
@@ -343,39 +344,11 @@
* @return port number
*/
public PortNumber tunnelPort(DeviceId deviceId) {
- Optional<PortNumber> port = getPortNumber(deviceId, DEFAULT_TUNNEL);
- return port.isPresent() ? port.get() : null;
- }
+ Port port = deviceService.getPorts(deviceId).stream()
+ .filter(p -> portName(p).contains(DEFAULT_TUNNEL))
+ .findFirst().orElse(null);
- /**
- * Returns host management interface port number if exists.
- *
- * @param deviceId integration bridge device id
- * @return port number; null if it does not exist
- */
- public PortNumber hostManagementPort(DeviceId deviceId) {
- CordVtnNode node = nodeByBridgeId(deviceId);
- if (node == null) {
- log.warn("Failed to get node for {}", deviceId);
- return null;
- }
-
- if (node.hostMgmtIface().isPresent()) {
- Optional<PortNumber> port = getPortNumber(deviceId, node.hostMgmtIface().get());
- return port.isPresent() ? port.get() : null;
- } else {
- return null;
- }
- }
-
- private Optional<PortNumber> getPortNumber(DeviceId deviceId, String portName) {
- PortNumber port = deviceService.getPorts(deviceId).stream()
- .filter(p -> p.annotations().value(AnnotationKeys.PORT_NAME).equals(portName) &&
- p.isEnabled())
- .map(Port::number)
- .findAny()
- .orElse(null);
- return Optional.ofNullable(port);
+ return port == null ? null : port.number();
}
/**
@@ -425,7 +398,8 @@
ovsdbClient.disconnect();
}
- pipeline.initPipeline(node);
+ pipeline.initPipeline(node, dataPort(node.integrationBridgeId()),
+ tunnelPort(node.integrationBridgeId()));
// adds existing instances to the host list
deviceService.getPorts(node.integrationBridgeId()).stream()
diff --git a/src/main/java/org/opencord/cordvtn/impl/CordVtnPipeline.java b/src/main/java/org/opencord/cordvtn/impl/CordVtnPipeline.java
index 4e01d2b..2aa9f1f 100644
--- a/src/main/java/org/opencord/cordvtn/impl/CordVtnPipeline.java
+++ b/src/main/java/org/opencord/cordvtn/impl/CordVtnPipeline.java
@@ -27,8 +27,7 @@
import org.onlab.packet.IpAddress;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
-import org.onosproject.net.AnnotationKeys;
-import org.onosproject.net.Port;
+import org.onlab.util.ItemNotFoundException;
import org.opencord.cordvtn.api.Constants;
import org.opencord.cordvtn.api.CordVtnNode;
import org.onosproject.core.ApplicationId;
@@ -51,11 +50,8 @@
import org.onosproject.net.flow.instructions.ExtensionTreatment;
import org.slf4j.Logger;
-import java.util.Optional;
-
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
-import static org.opencord.cordvtn.api.Constants.DEFAULT_TUNNEL;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -95,8 +91,6 @@
public static final int VXLAN_UDP_PORT = 4789;
public static final VlanId VLAN_WAN = VlanId.vlanId((short) 500);
- public static final String PROPERTY_TUNNEL_DST = "tunnelDst";
-
private ApplicationId appId;
@Activate
@@ -121,84 +115,19 @@
* Installs table miss rule to a give device.
*
* @param node cordvtn node
+ * @param dataPort data plane port number
+ * @param tunnelPort tunnel port number
*/
- public void initPipeline(CordVtnNode node) {
+ public void initPipeline(CordVtnNode node, PortNumber dataPort, PortNumber tunnelPort) {
checkNotNull(node);
- Optional<PortNumber> dataPort = getPortNumber(node.integrationBridgeId(), node.dataIface());
- Optional<PortNumber> tunnelPort = getPortNumber(node.integrationBridgeId(), DEFAULT_TUNNEL);
- if (!dataPort.isPresent() || !tunnelPort.isPresent()) {
- log.warn("Node is not in COMPLETE state");
- return;
- }
-
- Optional<PortNumber> hostMgmtPort = Optional.empty();
- if (node.hostMgmtIface().isPresent()) {
- hostMgmtPort = getPortNumber(node.integrationBridgeId(), node.hostMgmtIface().get());
- }
-
- processTableZero(node.integrationBridgeId(),
- dataPort.get(),
- node.dataIp().ip(),
- node.localMgmtIp().ip());
-
- processInPortTable(node.integrationBridgeId(),
- tunnelPort.get(),
- dataPort.get(),
- hostMgmtPort);
-
- processAccessTypeTable(node.integrationBridgeId(), dataPort.get());
- processVlanTable(node.integrationBridgeId(), dataPort.get());
+ processTableZero(node.integrationBridgeId(), dataPort, node.dataIp().ip());
+ processInPortTable(node.integrationBridgeId(), tunnelPort, dataPort);
+ processAccessTypeTable(node.integrationBridgeId(), dataPort);
+ processVlanTable(node.integrationBridgeId(), dataPort);
}
- private void processTableZero(DeviceId deviceId, PortNumber dataPort, IpAddress dataIp,
- IpAddress localMgmtIp) {
- vxlanShuttleRule(deviceId, dataPort, dataIp);
- localManagementBaseRule(deviceId, localMgmtIp.getIp4Address());
-
- // take all vlan tagged packet to the VLAN table
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchVlanId(VlanId.ANY)
- .build();
-
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .transition(TABLE_VLAN)
- .build();
-
- FlowRule flowRule = DefaultFlowRule.builder()
- .fromApp(appId)
- .withSelector(selector)
- .withTreatment(treatment)
- .withPriority(PRIORITY_MANAGEMENT)
- .forDevice(deviceId)
- .forTable(TABLE_ZERO)
- .makePermanent()
- .build();
-
- processFlowRule(true, flowRule);
-
- // take all other packets to the next table
- selector = DefaultTrafficSelector.builder()
- .build();
-
- treatment = DefaultTrafficTreatment.builder()
- .transition(TABLE_IN_PORT)
- .build();
-
- flowRule = DefaultFlowRule.builder()
- .fromApp(appId)
- .withSelector(selector)
- .withTreatment(treatment)
- .withPriority(PRIORITY_ZERO)
- .forDevice(deviceId)
- .forTable(TABLE_ZERO)
- .makePermanent()
- .build();
-
- processFlowRule(true, flowRule);
- }
-
- private void vxlanShuttleRule(DeviceId deviceId, PortNumber dataPort, IpAddress dataIp) {
+ private void processTableZero(DeviceId deviceId, PortNumber dataPort, IpAddress dataIp) {
// take vxlan packet out onto the physical port
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchInPort(PortNumber.LOCAL)
@@ -289,98 +218,52 @@
.build();
processFlowRule(true, flowRule);
- }
- private void localManagementBaseRule(DeviceId deviceId, Ip4Address localMgmtIp) {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_ARP)
- .matchArpTpa(localMgmtIp)
- .build();
-
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setOutput(PortNumber.LOCAL)
- .build();
-
- FlowRule flowRule = DefaultFlowRule.builder()
- .fromApp(appId)
- .withSelector(selector)
- .withTreatment(treatment)
- .withPriority(CordVtnPipeline.PRIORITY_MANAGEMENT)
- .forDevice(deviceId)
- .forTable(CordVtnPipeline.TABLE_ZERO)
- .makePermanent()
- .build();
-
- processFlowRule(true, flowRule);
-
+ // take all else to the next table
selector = DefaultTrafficSelector.builder()
- .matchInPort(PortNumber.LOCAL)
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchIPSrc(localMgmtIp.toIpPrefix())
.build();
treatment = DefaultTrafficTreatment.builder()
- .transition(CordVtnPipeline.TABLE_DST_IP)
+ .transition(TABLE_IN_PORT)
.build();
flowRule = DefaultFlowRule.builder()
.fromApp(appId)
.withSelector(selector)
.withTreatment(treatment)
- .withPriority(CordVtnPipeline.PRIORITY_MANAGEMENT)
+ .withPriority(PRIORITY_ZERO)
.forDevice(deviceId)
- .forTable(CordVtnPipeline.TABLE_ZERO)
+ .forTable(TABLE_ZERO)
.makePermanent()
.build();
processFlowRule(true, flowRule);
+ // take all vlan tagged packet to the VLAN table
selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchIPDst(localMgmtIp.toIpPrefix())
+ .matchVlanId(VlanId.ANY)
.build();
treatment = DefaultTrafficTreatment.builder()
- .setOutput(PortNumber.LOCAL)
+ .transition(TABLE_VLAN)
.build();
flowRule = DefaultFlowRule.builder()
.fromApp(appId)
.withSelector(selector)
.withTreatment(treatment)
- .withPriority(CordVtnPipeline.PRIORITY_MANAGEMENT)
+ .withPriority(PRIORITY_MANAGEMENT)
.forDevice(deviceId)
- .forTable(CordVtnPipeline.TABLE_ZERO)
- .makePermanent()
- .build();
-
- processFlowRule(true, flowRule);
-
- selector = DefaultTrafficSelector.builder()
- .matchInPort(PortNumber.LOCAL)
- .matchEthType(Ethernet.TYPE_ARP)
- .matchArpSpa(localMgmtIp)
- .build();
-
- treatment = DefaultTrafficTreatment.builder()
- .setOutput(PortNumber.CONTROLLER)
- .build();
-
- flowRule = DefaultFlowRule.builder()
- .fromApp(appId)
- .withSelector(selector)
- .withTreatment(treatment)
- .withPriority(CordVtnPipeline.PRIORITY_MANAGEMENT)
- .forDevice(deviceId)
- .forTable(CordVtnPipeline.TABLE_ZERO)
+ .forTable(TABLE_ZERO)
.makePermanent()
.build();
processFlowRule(true, flowRule);
}
- private void processInPortTable(DeviceId deviceId, PortNumber tunnelPort, PortNumber dataPort,
- Optional<PortNumber> hostMgmtPort) {
+ private void processInPortTable(DeviceId deviceId, PortNumber tunnelPort, PortNumber dataPort) {
+ checkNotNull(tunnelPort);
+
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchInPort(tunnelPort)
.build();
@@ -420,28 +303,6 @@
.build();
processFlowRule(true, flowRule);
-
- if (hostMgmtPort.isPresent()) {
- selector = DefaultTrafficSelector.builder()
- .matchInPort(hostMgmtPort.get())
- .build();
-
- treatment = DefaultTrafficTreatment.builder()
- .transition(TABLE_DST_IP)
- .build();
-
- flowRule = DefaultFlowRule.builder()
- .fromApp(appId)
- .withSelector(selector)
- .withTreatment(treatment)
- .withPriority(PRIORITY_DEFAULT)
- .forDevice(deviceId)
- .forTable(TABLE_IN_PORT)
- .makePermanent()
- .build();
-
- processFlowRule(true, flowRule);
- }
}
private void processAccessTypeTable(DeviceId deviceId, PortNumber dataPort) {
@@ -523,30 +384,23 @@
}
public ExtensionTreatment tunnelDstTreatment(DeviceId deviceId, Ip4Address remoteIp) {
- Device device = deviceService.getDevice(deviceId);
- if (device != null && !device.is(ExtensionTreatmentResolver.class)) {
- log.error("The extension treatment is not supported");
- return null;
- }
-
- ExtensionTreatmentResolver resolver = device.as(ExtensionTreatmentResolver.class);
- ExtensionTreatment treatment = resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
try {
- treatment.setPropertyValue(PROPERTY_TUNNEL_DST, remoteIp);
+ Device device = deviceService.getDevice(deviceId);
+ if (!device.is(ExtensionTreatmentResolver.class)) {
+ log.error("The extension treatment is not supported");
+ return null;
+
+ }
+
+ ExtensionTreatmentResolver resolver = device.as(ExtensionTreatmentResolver.class);
+ ExtensionTreatment treatment =
+ resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
+ treatment.setPropertyValue("tunnelDst", remoteIp);
return treatment;
- } catch (ExtensionPropertyException e) {
- log.warn("Failed to get tunnelDst extension treatment for {}", deviceId);
+ } catch (ItemNotFoundException | UnsupportedOperationException |
+ ExtensionPropertyException e) {
+ log.error("Failed to get extension instruction {}", deviceId);
return null;
}
}
-
- private Optional<PortNumber> getPortNumber(DeviceId deviceId, String portName) {
- PortNumber port = deviceService.getPorts(deviceId).stream()
- .filter(p -> p.annotations().value(AnnotationKeys.PORT_NAME).equals(portName) &&
- p.isEnabled())
- .map(Port::number)
- .findAny()
- .orElse(null);
- return Optional.ofNullable(port);
- }
}
diff --git a/src/main/java/org/opencord/cordvtn/impl/InstanceManager.java b/src/main/java/org/opencord/cordvtn/impl/InstanceManager.java
index d43a8c6..6269e98 100644
--- a/src/main/java/org/opencord/cordvtn/impl/InstanceManager.java
+++ b/src/main/java/org/opencord/cordvtn/impl/InstanceManager.java
@@ -70,7 +70,7 @@
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_RangeNotEnforced;
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
-import static org.onosproject.xosclient.api.VtnServiceApi.ServiceType.MANAGEMENT;
+import static org.onosproject.xosclient.api.VtnServiceApi.NetworkType.MANAGEMENT;
import static org.opencord.cordvtn.api.Constants.*;
import static org.slf4j.LoggerFactory.getLogger;
@@ -247,7 +247,7 @@
.domainServer(DEFAULT_DNS)
.assignmentStatus(Option_RangeNotEnforced);
- if (service.serviceType() != MANAGEMENT) {
+ if (service.networkType() != MANAGEMENT) {
ipBuilder = ipBuilder.routerAddress(service.serviceIp().getIp4Address());
}
diff --git a/src/main/java/org/opencord/cordvtn/impl/handler/ManagementInstanceHandler.java b/src/main/java/org/opencord/cordvtn/impl/handler/ManagementInstanceHandler.java
index 7a77b98..fe30781 100644
--- a/src/main/java/org/opencord/cordvtn/impl/handler/ManagementInstanceHandler.java
+++ b/src/main/java/org/opencord/cordvtn/impl/handler/ManagementInstanceHandler.java
@@ -32,7 +32,6 @@
import org.opencord.cordvtn.impl.AbstractInstanceHandler;
import org.opencord.cordvtn.api.Instance;
import org.opencord.cordvtn.api.InstanceHandler;
-import org.opencord.cordvtn.impl.CordVtnNodeManager;
import org.opencord.cordvtn.impl.CordVtnPipeline;
import java.util.Optional;
@@ -48,9 +47,6 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CordVtnPipeline pipeline;
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CordVtnNodeManager nodeManager;
-
@Activate
protected void activate() {
serviceType = Optional.of(MANAGEMENT);
@@ -64,85 +60,50 @@
@Override
public void instanceDetected(Instance instance) {
+ log.info("Instance is detected {}", instance);
+
VtnService service = getVtnService(instance.serviceId());
if (service == null) {
log.warn("Failed to get VtnService for {}", instance);
return;
}
-
- switch (service.networkType()) {
- case MANAGEMENT_LOCAL:
- log.info("LOCAL management instance detected {}", instance);
- localManagementRules(instance, true);
- break;
- case MANAGEMENT_HOSTS:
- log.info("HOSTS management instance detected {}", instance);
- hostsManagementRules(instance, true);
- break;
- default:
- break;
- }
+ localMgmtNetworkRules(instance, service, true);
}
@Override
public void instanceRemoved(Instance instance) {
+ log.info("Instance is removed {}", instance);
+
VtnService service = getVtnService(instance.serviceId());
if (service == null) {
log.warn("Failed to get VtnService for {}", instance);
return;
}
- switch (service.networkType()) {
- case MANAGEMENT_LOCAL:
- log.info("LOCAL management instance removed {}", instance);
- localManagementRules(instance, false);
- break;
- case MANAGEMENT_HOSTS:
- log.info("HOSTS management instance removed {}", instance);
- hostsManagementRules(instance, false);
- break;
- default:
- break;
+ // TODO check if any stale management network rules are
+ localMgmtNetworkRules(instance, service, false);
+ }
+
+ private void localMgmtNetworkRules(Instance instance, VtnService service, boolean install) {
+ managementPerInstanceRule(instance, install);
+ if (install) {
+ managementBaseRule(instance, service, true);
+ } else if (!hostService.getConnectedHosts(instance.deviceId()).stream()
+ .filter(host -> Instance.of(host).serviceId().equals(service.id()))
+ .findAny()
+ .isPresent()) {
+ managementBaseRule(instance, service, false);
}
}
- private void localManagementRules(Instance instance, boolean install) {
+ private void managementBaseRule(Instance instance, VtnService service, boolean install) {
TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchIPDst(instance.ipAddress().toIpPrefix())
+ .matchEthType(Ethernet.TYPE_ARP)
+ .matchArpTpa(service.serviceIp().getIp4Address())
.build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setEthDst(instance.mac())
- .setOutput(instance.portNumber())
- .build();
-
- FlowRule flowRule = DefaultFlowRule.builder()
- .fromApp(appId)
- .withSelector(selector)
- .withTreatment(treatment)
- .withPriority(CordVtnPipeline.PRIORITY_DEFAULT)
- .forDevice(instance.deviceId())
- .forTable(CordVtnPipeline.TABLE_DST_IP)
- .makePermanent()
- .build();
-
- pipeline.processFlowRule(install, flowRule);
- }
-
- private void hostsManagementRules(Instance instance, boolean install) {
- PortNumber hostMgmtPort = nodeManager.hostManagementPort(instance.deviceId());
- if (hostMgmtPort == null) {
- log.warn("Can not find host management port in {}", instance.deviceId());
- return;
- }
-
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchInPort(instance.portNumber())
- .build();
-
- TrafficTreatment treatment = DefaultTrafficTreatment.builder()
- .setOutput(hostMgmtPort)
+ .setOutput(PortNumber.LOCAL)
.build();
FlowRule flowRule = DefaultFlowRule.builder()
@@ -151,7 +112,74 @@
.withTreatment(treatment)
.withPriority(CordVtnPipeline.PRIORITY_MANAGEMENT)
.forDevice(instance.deviceId())
- .forTable(CordVtnPipeline.TABLE_IN_PORT)
+ .forTable(CordVtnPipeline.TABLE_ZERO)
+ .makePermanent()
+ .build();
+
+ pipeline.processFlowRule(install, flowRule);
+
+ selector = DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.LOCAL)
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPDst(service.subnet())
+ .build();
+
+ treatment = DefaultTrafficTreatment.builder()
+ .transition(CordVtnPipeline.TABLE_DST_IP)
+ .build();
+
+ flowRule = DefaultFlowRule.builder()
+ .fromApp(appId)
+ .withSelector(selector)
+ .withTreatment(treatment)
+ .withPriority(CordVtnPipeline.PRIORITY_MANAGEMENT)
+ .forDevice(instance.deviceId())
+ .forTable(CordVtnPipeline.TABLE_ZERO)
+ .makePermanent()
+ .build();
+
+ pipeline.processFlowRule(install, flowRule);
+
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPDst(service.serviceIp().toIpPrefix())
+ .build();
+
+ treatment = DefaultTrafficTreatment.builder()
+ .setOutput(PortNumber.LOCAL)
+ .build();
+
+ flowRule = DefaultFlowRule.builder()
+ .fromApp(appId)
+ .withSelector(selector)
+ .withTreatment(treatment)
+ .withPriority(CordVtnPipeline.PRIORITY_MANAGEMENT)
+ .forDevice(instance.deviceId())
+ .forTable(CordVtnPipeline.TABLE_ZERO)
+ .makePermanent()
+ .build();
+
+ pipeline.processFlowRule(install, flowRule);
+ }
+
+ private void managementPerInstanceRule(Instance instance, boolean install) {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchInPort(PortNumber.LOCAL)
+ .matchEthType(Ethernet.TYPE_ARP)
+ .matchArpTpa(instance.ipAddress().getIp4Address())
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setOutput(instance.portNumber())
+ .build();
+
+ FlowRule flowRule = DefaultFlowRule.builder()
+ .fromApp(appId)
+ .withSelector(selector)
+ .withTreatment(treatment)
+ .withPriority(CordVtnPipeline.PRIORITY_MANAGEMENT)
+ .forDevice(instance.deviceId())
+ .forTable(CordVtnPipeline.TABLE_ZERO)
.makePermanent()
.build();