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-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFlowRuleManager.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFlowRuleManager.java
index a79eeb0..8d72286 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFlowRuleManager.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFlowRuleManager.java
@@ -130,9 +130,7 @@
nodeService.addListener(internalNodeListener);
localNodeId = clusterService.getLocalNode().id();
leadershipService.runForLeadership(appId.name());
- nodeService.completeNodes(WORKER)
- .forEach(node -> initializeWorkerNodePipeline(node.intgBridge()));
-
+ nodeService.completeNodes(WORKER).forEach(this::initializeGatewayNodePipeline);
log.info("Started");
}
@@ -236,7 +234,8 @@
}));
}
- protected void initializeGatewayNodePipeline(DeviceId deviceId) {
+ protected void initializeGatewayNodePipeline(KubevirtNode kubevirtNode) {
+ DeviceId deviceId = kubevirtNode.intgBridge();
// for inbound to gateway entry table transition
connectTables(deviceId, STAT_INBOUND_TABLE, GW_ENTRY_TABLE);
@@ -247,9 +246,15 @@
setupGatewayNodeDropTable(deviceId);
// for setting up default Forwarding table behavior which is NORMAL
- setupForwardingTable(deviceId);
+ setupNormalTable(deviceId, FORWARDING_TABLE);
+
+ kubevirtNode.phyIntfs().stream().filter(intf -> intf.physBridge() != null)
+ .forEach(phyIntf -> {
+ setupNormalTable(phyIntf.physBridge(), STAT_INBOUND_TABLE);
+ });
}
- protected void initializeWorkerNodePipeline(DeviceId deviceId) {
+ protected void initializeWorkerNodePipeline(KubevirtNode kubevirtNode) {
+ DeviceId deviceId = kubevirtNode.intgBridge();
// for inbound table transition
connectTables(deviceId, STAT_INBOUND_TABLE, VTAP_INBOUND_TABLE);
connectTables(deviceId, VTAP_INBOUND_TABLE, DHCP_TABLE);
@@ -264,7 +269,12 @@
setupArpTable(deviceId);
// for setting up default Forwarding table behavior which is NORMAL
- setupForwardingTable(deviceId);
+ setupNormalTable(deviceId, FORWARDING_TABLE);
+
+ kubevirtNode.phyIntfs().stream().filter(intf -> intf.physBridge() != null)
+ .forEach(phyIntf -> {
+ setupNormalTable(phyIntf.physBridge(), STAT_INBOUND_TABLE);
+ });
}
private void setupArpTable(DeviceId deviceId) {
@@ -284,7 +294,7 @@
true);
}
- private void setupForwardingTable(DeviceId deviceId) {
+ private void setupNormalTable(DeviceId deviceId, int tableNum) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
.setOutput(PortNumber.NORMAL);
@@ -295,7 +305,7 @@
selector.build(),
treatment.build(),
LOW_PRIORITY,
- FORWARDING_TABLE,
+ tableNum,
true);
}
@@ -346,9 +356,9 @@
}
if (event.subject().type().equals(WORKER)) {
- initializeWorkerNodePipeline(node.intgBridge());
+ initializeWorkerNodePipeline(node);
} else {
- initializeGatewayNodePipeline(node.intgBridge());
+ initializeGatewayNodePipeline(node);
}
});
break;
diff --git a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/DefaultKubevirtPhyInterface.java b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/DefaultKubevirtPhyInterface.java
index 1cae8f2..5d95b78 100644
--- a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/DefaultKubevirtPhyInterface.java
+++ b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/DefaultKubevirtPhyInterface.java
@@ -16,6 +16,7 @@
package org.onosproject.kubevirtnode.api;
import com.google.common.base.MoreObjects;
+import org.onosproject.net.DeviceId;
import java.util.Objects;
@@ -28,6 +29,7 @@
private final String network;
private final String intf;
+ private final DeviceId physBridge;
private static final String NOT_NULL_MSG = "% cannot be null";
@@ -36,10 +38,12 @@
*
* @param network network that this physical interface connects with
* @param intf name of physical interface
+ * @param physBridge device id of the physical bridge
*/
- protected DefaultKubevirtPhyInterface(String network, String intf) {
+ protected DefaultKubevirtPhyInterface(String network, String intf, DeviceId physBridge) {
this.network = network;
this.intf = intf;
+ this.physBridge = physBridge;
}
@Override
@@ -53,6 +57,11 @@
}
@Override
+ public DeviceId physBridge() {
+ return physBridge;
+ }
+
+ @Override
public boolean equals(Object o) {
if (this == o) {
return true;
@@ -62,12 +71,13 @@
}
DefaultKubevirtPhyInterface that = (DefaultKubevirtPhyInterface) o;
return network.equals(that.network) &&
- intf.equals(that.intf);
+ intf.equals(that.intf) &&
+ physBridge.equals(that.physBridge);
}
@Override
public int hashCode() {
- return Objects.hash(network, intf);
+ return Objects.hash(network, intf, physBridge);
}
@Override
@@ -75,6 +85,7 @@
return MoreObjects.toStringHelper(this)
.add("network", network)
.add("intf", intf)
+ .add("physnetBridge", physBridge)
.toString();
}
@@ -91,6 +102,7 @@
private String network;
private String intf;
+ private DeviceId physBridge;
// private constructor not intended to use from external
private Builder() {
@@ -100,8 +112,9 @@
public KubevirtPhyInterface build() {
checkArgument(network != null, NOT_NULL_MSG, "network");
checkArgument(intf != null, NOT_NULL_MSG, "intf");
+ checkArgument(physBridge != null, NOT_NULL_MSG, "physBridge");
- return new DefaultKubevirtPhyInterface(network, intf);
+ return new DefaultKubevirtPhyInterface(network, intf, physBridge);
}
@Override
@@ -115,5 +128,12 @@
this.intf = intf;
return this;
}
+
+ @Override
+ public KubevirtPhyInterface.Builder physBridge(DeviceId physBridge) {
+ this.physBridge = physBridge;
+ return this;
+ }
+
}
}
diff --git a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtNodeService.java b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtNodeService.java
index 41e90a3..e9ed65b 100644
--- a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtNodeService.java
+++ b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtNodeService.java
@@ -99,4 +99,12 @@
* @return kubevirt node
*/
KubevirtNode nodeByTunBridge(DeviceId deviceId);
+
+ /**
+ * Returns the node with the specified physical device ID.
+ *
+ * @param deviceId device id
+ * @return node
+ */
+ KubevirtNode nodeByPhyBridge(DeviceId deviceId);
}
diff --git a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtPhyInterface.java b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtPhyInterface.java
index b3e0061..d17d796 100644
--- a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtPhyInterface.java
+++ b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtPhyInterface.java
@@ -15,6 +15,8 @@
*/
package org.onosproject.kubevirtnode.api;
+import org.onosproject.net.DeviceId;
+
/**
* Representation of a KubeVirt physical interface used in KubeVirt networking service.
*/
@@ -34,6 +36,13 @@
String intf();
/**
+ * Returns the device ID of the physical interface bridge at the node.
+ *
+ * @return device id
+ */
+ DeviceId physBridge();
+
+ /**
* Builder of kubevirt physical interface.
*/
interface Builder {
@@ -55,5 +64,13 @@
* @return kubevirt physical interface builder
*/
Builder intf(String intf);
+
+ /**
+ * Returns kubevirt physical interface builder with supplied.
+ *
+ * @param physBridge device id of the physical bridge
+ * @return kubevirt physical interface builder
+ */
+ Builder physBridge(DeviceId physBridge);
}
}
diff --git a/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtNodeTest.java b/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtNodeTest.java
index d66528c..6ad846b 100644
--- a/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtNodeTest.java
+++ b/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtNodeTest.java
@@ -21,6 +21,7 @@
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
import java.util.List;
@@ -47,6 +48,7 @@
private static final String PHY_INTF_NETWORK = "mgmtnetwork";
private static final String PHY_INTF_NAME = "eth3";
+ private static final DeviceId BRIDGE = DeviceId.deviceId("phys1");
private static final String GATEWAY_BRIDGE_NAME = "gateway";
@@ -203,6 +205,7 @@
KubevirtPhyInterface phyIntf = DefaultKubevirtPhyInterface.builder()
.intf(PHY_INTF_NAME)
.network(PHY_INTF_NETWORK)
+ .physBridge(BRIDGE)
.build();
return ImmutableList.of(phyIntf);
diff --git a/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtPhyInterfaceTest.java b/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtPhyInterfaceTest.java
index 37ecdf4..73908f2 100644
--- a/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtPhyInterfaceTest.java
+++ b/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtPhyInterfaceTest.java
@@ -17,6 +17,7 @@
import com.google.common.testing.EqualsTester;
import org.junit.Test;
+import org.onosproject.net.DeviceId;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
@@ -30,13 +31,15 @@
private static final String NETWORK_2 = "oamnetwork";
private static final String INTERFACE_1 = "eth3";
private static final String INTERFACE_2 = "eth4";
+ private static final DeviceId BRIDGE_1 = DeviceId.deviceId("phys1");
+ private static final DeviceId BRIDGE_2 = DeviceId.deviceId("phys2");
- private static final KubevirtPhyInterface KV_PHY_INTF_1 =
- new DefaultKubevirtPhyInterface(NETWORK_1, INTERFACE_1);
- private static final KubevirtPhyInterface KV_PHY_INTF_2 =
- new DefaultKubevirtPhyInterface(NETWORK_1, INTERFACE_1);
- private static final KubevirtPhyInterface KV_PHY_INTF_3 =
- new DefaultKubevirtPhyInterface(NETWORK_2, INTERFACE_2);
+ private static final KubevirtPhyInterface KV_PHY_INTF_1 = createPhysIntf(
+ NETWORK_1, INTERFACE_1, BRIDGE_1);
+ private static final KubevirtPhyInterface KV_PHY_INTF_2 = createPhysIntf(
+ NETWORK_1, INTERFACE_1, BRIDGE_1);
+ private static final KubevirtPhyInterface KV_PHY_INTF_3 = createPhysIntf(
+ NETWORK_2, INTERFACE_2, BRIDGE_2);
@Test
public void testEquality() {
@@ -53,4 +56,13 @@
assertThat(phyIntf.network(), is(NETWORK_1));
assertThat(phyIntf.intf(), is(INTERFACE_1));
}
+
+ private static KubevirtPhyInterface createPhysIntf(String network,
+ String intf, DeviceId physBridge) {
+ return DefaultKubevirtPhyInterface.builder()
+ .network(network)
+ .intf(intf)
+ .physBridge(physBridge)
+ .build();
+ }
}
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/codec/KubevirtPhyInterfaceCodec.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/codec/KubevirtPhyInterfaceCodec.java
index 3ba0164..796a1b1 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/codec/KubevirtPhyInterfaceCodec.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/codec/KubevirtPhyInterfaceCodec.java
@@ -15,11 +15,13 @@
*/
package org.onosproject.kubevirtnode.codec;
+import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.codec.CodecContext;
import org.onosproject.codec.JsonCodec;
import org.onosproject.kubevirtnode.api.DefaultKubevirtPhyInterface;
import org.onosproject.kubevirtnode.api.KubevirtPhyInterface;
+import org.onosproject.net.DeviceId;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.util.Tools.nullIsIllegal;
@@ -31,6 +33,7 @@
private static final String NETWORK = "network";
private static final String INTERFACE = "intf";
+ private static final String PHYS_BRIDGE_ID = "physBridgeId";
private static final String MISSING_MESSAGE = " is required in KubevirtPhyInterface";
@@ -38,9 +41,15 @@
public ObjectNode encode(KubevirtPhyInterface phyIntf, CodecContext context) {
checkNotNull(phyIntf, "Kubevirt physical interface cannot be null");
- return context.mapper().createObjectNode()
+ ObjectNode result = context.mapper().createObjectNode()
.put(NETWORK, phyIntf.network())
.put(INTERFACE, phyIntf.intf());
+
+ if (phyIntf.physBridge() != null) {
+ result.put(PHYS_BRIDGE_ID, phyIntf.physBridge().toString());
+ }
+
+ return result;
}
@Override
@@ -54,9 +63,15 @@
String intf = nullIsIllegal(json.get(INTERFACE).asText(),
INTERFACE + MISSING_MESSAGE);
- return DefaultKubevirtPhyInterface.builder()
+ KubevirtPhyInterface.Builder builder = DefaultKubevirtPhyInterface.builder()
.network(network)
- .intf(intf)
- .build();
+ .intf(intf);
+
+ JsonNode physBridgeJson = json.get(PHYS_BRIDGE_ID);
+ if (physBridgeJson != null) {
+ builder.physBridge(DeviceId.deviceId(physBridgeJson.asText()));
+ }
+
+ return builder.build();
}
}
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) {
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/KubevirtNodeManager.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/KubevirtNodeManager.java
index 4e7e39e..f16837e 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/KubevirtNodeManager.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/KubevirtNodeManager.java
@@ -61,6 +61,7 @@
import static org.onosproject.kubevirtnode.api.Constants.TUNNEL_BRIDGE;
import static org.onosproject.kubevirtnode.impl.OsgiPropertyConstants.OVSDB_PORT;
import static org.onosproject.kubevirtnode.impl.OsgiPropertyConstants.OVSDB_PORT_NUM_DEFAULT;
+import static org.onosproject.kubevirtnode.util.KubevirtNodeUtil.genDpidFromName;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -305,6 +306,21 @@
.findFirst().orElse(null);
}
+ @Override
+ public KubevirtNode nodeByPhyBridge(DeviceId deviceId) {
+ return nodeStore.nodes().stream()
+ .filter(node -> hasPhyBridge(node, deviceId))
+ .findAny()
+ .orElse(null);
+ }
+
+ private boolean hasPhyBridge(KubevirtNode node, DeviceId deviceId) {
+ return node.phyIntfs().stream()
+ .filter(phyIntf -> phyIntf.physBridge().equals(deviceId))
+ .findAny()
+ .isPresent();
+ }
+
private boolean hasIntgBridge(DeviceId deviceId, String hostname) {
Optional<KubevirtNode> existNode = nodeStore.nodes().stream()
.filter(n -> !n.hostname().equals(hostname))
@@ -323,15 +339,6 @@
return existNode.isPresent();
}
- private String genDpidFromName(String name) {
- if (name != null) {
- String hexString = Integer.toHexString(name.hashCode());
- return OF_PREFIX + Strings.padStart(hexString, 16, '0');
- }
-
- return null;
- }
-
private class InternalNodeStoreDelegate implements KubevirtNodeStoreDelegate {
@Override
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/util/KubevirtNodeUtil.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/util/KubevirtNodeUtil.java
index 66b1af8..7107285 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/util/KubevirtNodeUtil.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/util/KubevirtNodeUtil.java
@@ -38,6 +38,7 @@
import org.onosproject.kubevirtnode.api.KubevirtNodeState;
import org.onosproject.kubevirtnode.api.KubevirtPhyInterface;
import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.behaviour.BridgeConfig;
import org.onosproject.net.behaviour.BridgeName;
import org.onosproject.net.device.DeviceService;
@@ -86,6 +87,7 @@
private static final String GATEWAY_BRIDGE_NAME = "gatewayBridgeName";
private static final String NETWORK_KEY = "network";
private static final String INTERFACE_KEY = "interface";
+ private static final String PHYS_BRIDGE_ID = "physBridgeId";
private static final int PORT_NAME_MAX_LENGTH = 15;
@@ -365,8 +367,20 @@
String intf = object.getString(INTERFACE_KEY);
if (network != null && intf != null) {
+ String physBridgeId;
+ if (object.has(PHYS_BRIDGE_ID)) {
+ physBridgeId = object.getString(PHYS_BRIDGE_ID);
+ } else {
+ physBridgeId = genDpidFromName(network + intf + hostname);
+ log.trace("host {} physnet dpid for network {} intf {} is null so generate dpid {}",
+ hostname, network, intf, physBridgeId);
+ }
+
phys.add(DefaultKubevirtPhyInterface.builder()
- .network(network).intf(intf).build());
+ .network(network)
+ .intf(intf)
+ .physBridge(DeviceId.deviceId(physBridgeId))
+ .build());
}
}
}
@@ -414,6 +428,20 @@
}
/**
+ * Generates a unique dpid from given name.
+ *
+ * @param name name
+ * @return device id in string
+ */
+ public static String genDpidFromName(String name) {
+ if (name != null) {
+ String hexString = Integer.toHexString(name.hashCode());
+ return OF_PREFIX + Strings.padStart(hexString, 16, '0');
+ }
+ return null;
+ }
+
+ /**
* Resolve a DNS with the given DNS server and hostname.
*
* @param hostname hostname to be resolved
diff --git a/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtNodeCodecTest.java b/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtNodeCodecTest.java
index eee6bf7..ae3467a 100644
--- a/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtNodeCodecTest.java
+++ b/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtNodeCodecTest.java
@@ -59,6 +59,10 @@
final CoreService mockCoreService = createMock(CoreService.class);
private static final String REST_APP_ID = "org.onosproject.rest";
+ private static final DeviceId DEVICE_ID_1 = DeviceId.deviceId(String.format("of:%016d", 1));
+ private static final DeviceId DEVICE_ID_2 = DeviceId.deviceId(String.format("of:%016d", 2));
+ private static final DeviceId DEVICE_ID_3 = DeviceId.deviceId(String.format("of:%016d", 3));
+
@Before
public void setUp() {
@@ -83,11 +87,13 @@
KubevirtPhyInterface phyIntf1 = DefaultKubevirtPhyInterface.builder()
.network("mgmtnetwork")
.intf("eth3")
+ .physBridge(DEVICE_ID_1)
.build();
KubevirtPhyInterface phyIntf2 = DefaultKubevirtPhyInterface.builder()
.network("oamnetwork")
.intf("eth4")
+ .physBridge(DEVICE_ID_2)
.build();
KubevirtNode node = DefaultKubevirtNode.builder()
@@ -125,9 +131,11 @@
node.phyIntfs().forEach(intf -> {
if (intf.network().equals("mgmtnetwork")) {
assertThat(intf.intf(), is("eth3"));
+ assertThat(intf.physBridge().toString(), is("of:00000000000000a3"));
}
if (intf.network().equals("oamnetwork")) {
assertThat(intf.intf(), is("eth4"));
+ assertThat(intf.physBridge().toString(), is("of:00000000000000a4"));
}
});
}
diff --git a/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/codec/KubevirtWorkerNode.json b/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/codec/KubevirtWorkerNode.json
index 78a8687..4db7b1a 100644
--- a/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/codec/KubevirtWorkerNode.json
+++ b/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/codec/KubevirtWorkerNode.json
@@ -8,11 +8,14 @@
"phyIntfs": [
{
"network": "mgmtnetwork",
- "intf": "eth3"
+ "intf": "eth3",
+ "physBridgeId": "of:00000000000000a3"
+
},
{
"network": "oamnetwork",
- "intf": "eth4"
+ "intf": "eth4",
+ "physBridgeId": "of:00000000000000a4"
}
]
}
\ No newline at end of file