Connects to all the physical bridges in Kubevirt Node app to deal with the case that the physical port is disabled.
Change-Id: I9706cd4b670fbbb7ffdaaa2924fb893c801b2253
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtNodeHandler.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtNodeHandler.java
index 00aa0bf..0850ba2 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtNodeHandler.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtNodeHandler.java
@@ -88,6 +88,7 @@
import static org.onosproject.kubevirtnode.api.Constants.TUNNEL_TO_INTEGRATION;
import static org.onosproject.kubevirtnode.api.Constants.VXLAN;
import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.GATEWAY;
+import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.WORKER;
import static org.onosproject.kubevirtnode.api.KubevirtNodeService.APP_ID;
import static org.onosproject.kubevirtnode.api.KubevirtNodeState.COMPLETE;
import static org.onosproject.kubevirtnode.api.KubevirtNodeState.DEVICE_CREATED;
@@ -585,18 +586,42 @@
log.error("Exception caused during init state checking...");
}
- String bridgeName = BRIDGE_PREFIX + phyIntf.network();
String patchPortName = structurePortName(
INTEGRATION_TO_PHYSICAL_PREFIX + phyIntf.network());
- if (!(hasPhyBridge(node, bridgeName) &&
- hasPhyPatchPort(node, patchPortName) &&
- hasPhyIntf(node, phyIntf.intf()))) {
- log.warn("PhyBridge {}", hasPhyBridge(node, bridgeName));
- log.warn("hasPhyPatchPort {}", hasPhyPatchPort(node, patchPortName));
- log.warn("hasPhyIntf {}", hasPhyIntf(node, phyIntf.intf()));
- return false;
+ if (node.type() == WORKER) {
+ String bridgeName = BRIDGE_PREFIX + phyIntf.network();
+ if (!(hasPhyBridge(node, bridgeName) &&
+ hasPhyPatchPort(node, patchPortName) &&
+ hasPhyIntf(node, phyIntf.intf()))) {
+ log.warn("PhyBridge {}", hasPhyBridge(node, bridgeName));
+ log.warn("hasPhyPatchPort {}", hasPhyPatchPort(node, patchPortName));
+ log.warn("hasPhyIntf {}", hasPhyIntf(node, phyIntf.intf()));
+ return false;
+ }
+ } else {
+ //In case node type is GATEWAY, we create physical bridges connected to the contoller.
+ //By doing so, ONOS immediately recognizes the status of physical interface and performs RM procedures.
+ Port phyIntfPort = deviceService.getPorts(phyIntf.physBridge()).stream()
+ .filter(port -> port.annotations().value(PORT_NAME).equals(phyIntf.intf()))
+ .findAny().orElse(null);
+ if (phyIntfPort == null) {
+ log.warn("There's no connected physical port {} on physical device {}",
+ phyIntf.intf(), phyIntf.physBridge());
+ }
+
+ if (!(deviceService.isAvailable(phyIntf.physBridge()) &&
+ hasPhyPatchPort(node, patchPortName) &&
+ hasPhyIntf(node, phyIntf.intf()) &&
+ phyIntfPort.isEnabled())) {
+ log.warn("PhysBridge {}", deviceService.isAvailable(phyIntf.physBridge()));
+ log.warn("hasPhyPatchPort {}", hasPhyPatchPort(node, patchPortName));
+ log.warn("hasPhyIntf {}", hasPhyIntf(node, phyIntf.intf()));
+ log.warn("physical interface port {}", phyIntfPort.isEnabled());
+ return false;
+ }
}
+
}
if (node.type() == GATEWAY) {
@@ -610,6 +635,12 @@
return true;
}
+ private boolean hasPhyBridge(KubevirtNode node, String bridgeName) {
+ BridgeConfig bridgeConfig =
+ deviceService.getDevice(node.ovsdb()).as(BridgeConfig.class);
+ return bridgeConfig.getBridges().stream()
+ .anyMatch(br -> br.name().equals(bridgeName));
+ }
/**
* Configures the kubernetes node with new state.
*
@@ -630,14 +661,21 @@
String bridgeName = BRIDGE_PREFIX + pi.network();
String patchPortName =
structurePortName(INTEGRATION_TO_PHYSICAL_PREFIX + pi.network());
-
- if (!hasPhyBridge(node, bridgeName)) {
+ if (node.type() == WORKER && !hasPhyBridge(node, bridgeName)) {
createPhysicalBridge(node, pi);
createPhysicalPatchPorts(node, pi);
attachPhysicalPort(node, pi);
- log.info("Creating physnet bridge {}", bridgeName);
- log.info("Creating patch ports for physnet {}", bridgeName);
+ log.info("Creating physnet bridge {} for worker node {}", bridgeName, node.hostname());
+ log.info("Creating patch ports for physnet {} for worker node {}", bridgeName, node.hostname());
+
+ } else if (node.type() == GATEWAY && (!deviceService.isAvailable(pi.physBridge()))) {
+ createPhysicalBridgeWithConnectedMode(node, pi);
+ createPhysicalPatchPorts(node, pi);
+ attachPhysicalPort(node, pi);
+
+ log.info("Creating physnet bridge {} for gateway node {}", bridgeName, node.hostname());
+ log.info("Creating patch ports for physnet {} for gateway node {}", bridgeName, node.hostname());
} else {
// in case physical bridge exists, but patch port is missing,
// we will add patch port to connect br-physnet with physical bridge
@@ -728,13 +766,6 @@
});
}
- private boolean hasPhyBridge(KubevirtNode node, String bridgeName) {
- BridgeConfig bridgeConfig =
- deviceService.getDevice(node.ovsdb()).as(BridgeConfig.class);
- return bridgeConfig.getBridges().stream()
- .anyMatch(br -> br.name().equals(bridgeName));
- }
-
private boolean hasPhyPatchPort(KubevirtNode node, String patchPortName) {
List<Port> ports = deviceService.getPorts(node.intgBridge());
return ports.stream().anyMatch(p ->
@@ -762,6 +793,44 @@
bridgeConfig.addBridge(builder.build());
}
+ private void createPhysicalBridgeWithConnectedMode(KubevirtNode osNode,
+ KubevirtPhyInterface phyInterface) {
+ Device device = deviceService.getDevice(osNode.ovsdb());
+ IpAddress controllerIp = apiConfigService.apiConfig().controllerIp();
+ String serviceFqdn = apiConfigService.apiConfig().serviceFqdn();
+ IpAddress serviceIp = null;
+
+ if (controllerIp == null) {
+ if (serviceFqdn != null) {
+ serviceIp = resolveHostname(serviceFqdn);
+ }
+
+ if (serviceIp != null) {
+ controllerIp = serviceIp;
+ } else {
+ controllerIp = apiConfigService.apiConfig().ipAddress();
+ }
+ }
+
+ ControllerInfo controlInfo = new ControllerInfo(controllerIp, DEFAULT_OFPORT, DEFAULT_OF_PROTO);
+ List<ControllerInfo> controllers = Lists.newArrayList(controlInfo);
+
+ String dpid = phyInterface.physBridge().toString().substring(DPID_BEGIN);
+
+ String bridgeName = BRIDGE_PREFIX + phyInterface.network();
+
+ BridgeDescription.Builder builder = DefaultBridgeDescription.builder()
+ .name(bridgeName)
+ .failMode(BridgeDescription.FailMode.SECURE)
+ .datapathId(dpid)
+ .mcastSnoopingEnable()
+ .disableInBand()
+ .controllers(controllers);
+
+ BridgeConfig bridgeConfig = device.as(BridgeConfig.class);
+ bridgeConfig.addBridge(builder.build());
+ }
+
private void removePhysicalBridge(KubevirtNode node, String network) {
Device device = deviceService.getDevice(node.ovsdb());
@@ -843,6 +912,17 @@
addOrRemoveSystemInterface(node, physicalDeviceId, portName, deviceService, false);
}
+ private KubevirtNode nodeByTunOrPhyBridge(DeviceId deviceId) {
+ KubevirtNode node = nodeAdminService.nodeByTunBridge(deviceId);
+ if (node == null) {
+ node = nodeAdminService.nodeByPhyBridge(deviceId);
+ if (node == null) {
+ return null;
+ }
+ }
+ return node;
+ }
+
/**
* An internal OVSDB listener. This listener is used for listening the
* network facing events from OVSDB device. If a new OVSDB device is detected,
@@ -923,7 +1003,7 @@
break;
case PORT_UPDATED:
case PORT_ADDED:
- eventExecutor.execute(() -> processPortAddition(device, port));
+ eventExecutor.execute(() -> processPortAdditionOrUpdate(device, port));
break;
case PORT_REMOVED:
eventExecutor.execute(() -> processPortRemoval(device, port));
@@ -962,12 +1042,12 @@
}
}
- void processPortAddition(Device device, Port port) {
+ void processPortAdditionOrUpdate(Device device, Port port) {
if (!isRelevantHelper()) {
return;
}
- KubevirtNode node = nodeAdminService.nodeByTunBridge(device.id());
+ KubevirtNode node = nodeByTunOrPhyBridge(device.id());
if (node == null) {
return;
@@ -983,6 +1063,24 @@
portName, device.id());
bootstrapNode(node);
}
+
+ //When the physical port is down, in the middle of normal operation, we set the node state to INCOMPLTE
+ //so that respective handlers do their related jobs.
+ if (node.state() == COMPLETE && node.type().equals(GATEWAY) && !port.isEnabled()) {
+ node.phyIntfs().stream()
+ .filter(pi -> pi.intf().equals(portName))
+ .findAny()
+ .ifPresent(pi -> setState(node, INCOMPLETE));
+ }
+
+ //When the physical port up again, we set the node state to INIT
+ //so that respective handlers do their related jobs.
+ if (node.state() == INCOMPLETE && node.type().equals(GATEWAY) && port.isEnabled()) {
+ node.phyIntfs().stream()
+ .filter(pi -> pi.intf().equals(portName))
+ .findAny()
+ .ifPresent(pi -> setState(node, INIT));
+ }
}
void processPortRemoval(Device device, Port port) {