Support VLAN network in gateway node.
Change-Id: Ia18287bf072e47787ba71865e8f8c4cb032dc455
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java
index 9def76f..18caff1 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java
@@ -52,6 +52,7 @@
import org.onosproject.net.behaviour.InterfaceConfig;
import org.onosproject.net.behaviour.PatchDescription;
import org.onosproject.net.device.DeviceAdminService;
+import org.onosproject.net.driver.DriverService;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
@@ -75,6 +76,7 @@
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.kubevirtnetworking.api.Constants.DEFAULT_GATEWAY_MAC;
import static org.onosproject.kubevirtnetworking.api.Constants.KUBEVIRT_NETWORKING_APP_ID;
+import static org.onosproject.kubevirtnetworking.api.Constants.PRE_FLAT_TABLE;
import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ARP_GATEWAY_RULE;
import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_DHCP_RULE;
import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_FORWARDING_RULE;
@@ -95,6 +97,8 @@
import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveEthSrcToDstExtension;
import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildMoveIpSrcToDstExtension;
import static org.onosproject.kubevirtnode.api.Constants.TUNNEL_BRIDGE;
+import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.GATEWAY;
+import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.WORKER;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -133,6 +137,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected KubevirtFlowRuleService flowService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected DriverService driverService;
+
private final KubevirtNetworkListener networkListener = new InternalNetworkEventListener();
private final KubevirtNodeListener nodeListener = new InternalNodeEventListener();
@@ -274,8 +281,10 @@
setDhcpRule(deviceId, true);
setForwardingRule(deviceId, true);
- setGatewayArpRule(node, network, true);
- setGatewayIcmpRule(node, network, true);
+ setGatewayArpRule(network, TENANT_ARP_TABLE,
+ network.tenantDeviceId(node.hostname()), true);
+ setGatewayIcmpRule(network, TENANT_ICMP_TABLE,
+ network.tenantDeviceId(node.hostname()), true);
log.info("Install default flow rules for tenant bridge {}", network.tenantBridgeName());
}
@@ -318,8 +327,9 @@
install);
}
- private void setGatewayArpRule(KubevirtNode node, KubevirtNetwork network, boolean install) {
- Device device = deviceService.getDevice(network.tenantDeviceId(node.hostname()));
+ private void setGatewayArpRule(KubevirtNetwork network,
+ int tableNum, DeviceId deviceId, boolean install) {
+ Device device = deviceService.getDevice(deviceId);
TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
sBuilder.matchEthType(EthType.EtherType.ARP.ethType().toShort())
@@ -342,13 +352,14 @@
sBuilder.build(),
tBuilder.build(),
PRIORITY_ARP_GATEWAY_RULE,
- TENANT_ARP_TABLE,
+ tableNum,
install
);
}
- private void setGatewayIcmpRule(KubevirtNode node, KubevirtNetwork network, boolean install) {
- DeviceId deviceId = network.tenantDeviceId(node.hostname());
+ private void
+ setGatewayIcmpRule(KubevirtNetwork network,
+ int tableNum, DeviceId deviceId, boolean install) {
TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_ICMP)
@@ -374,10 +385,36 @@
sBuilder.build(),
tBuilder.build(),
PRIORITY_ICMP_RULE,
- TENANT_ICMP_TABLE,
+ tableNum,
install);
}
+
+ private void initGatewayNodeBridge(KubevirtNetwork network, boolean install) {
+ KubevirtNode electedGateway = gatewayNodeForSpecifiedNetwork(network);
+ if (electedGateway == null) {
+ log.warn("There's no elected gateway for the network {}", network.name());
+ }
+
+ setGatewayArpRule(network, PRE_FLAT_TABLE, electedGateway.intgBridge(), install);
+ setGatewayIcmpRule(network, PRE_FLAT_TABLE, electedGateway.intgBridge(), install);
+ }
+
+ /**
+ * Returns the gateway node for the specified network.
+ * Among gateways, only one gateway would act as a gateway per network.
+ *
+ * @param network kubevirt network
+ * @return gateway node which would act as the gateway for the network
+ */
+ private KubevirtNode gatewayNodeForSpecifiedNetwork(KubevirtNetwork network) {
+ //TODO: would implement election logic for each network.
+ //TODO: would implement cleanup logic in case a gateway node is added
+ // and the election is changed
+ return nodeService.completeNodes(GATEWAY).stream()
+ .findFirst().orElse(null);
+ }
+
private class InternalNetworkEventListener implements KubevirtNetworkListener {
private boolean isRelevantHelper() {
@@ -413,6 +450,8 @@
break;
case FLAT:
case VLAN:
+ initGatewayNodeBridge(network, true);
+ break;
default:
// do nothing
break;
@@ -432,6 +471,8 @@
break;
case FLAT:
case VLAN:
+ initGatewayNodeBridge(network, false);
+ break;
default:
// do nothing
break;
@@ -487,23 +528,40 @@
return;
}
- for (KubevirtNetwork network : networkService.networks()) {
- switch (network.type()) {
- case VXLAN:
- case GRE:
- case GENEVE:
- if (network.segmentId() == null) {
- continue;
- }
- createBridge(node, network);
- createPatchInterface(node, network);
- setDefaultRules(node, network);
- break;
- case FLAT:
- case VLAN:
- default:
- // do nothing
- break;
+ if (node.type().equals(WORKER)) {
+ for (KubevirtNetwork network : networkService.networks()) {
+ switch (network.type()) {
+ case VXLAN:
+ case GRE:
+ case GENEVE:
+ if (network.segmentId() == null) {
+ continue;
+ }
+ createBridge(node, network);
+ createPatchInterface(node, network);
+ setDefaultRules(node, network);
+ break;
+ case FLAT:
+ case VLAN:
+ default:
+ // do nothing
+ break;
+ }
+ }
+ } else if (node.type().equals(GATEWAY)) {
+ for (KubevirtNetwork network : networkService.networks()) {
+ switch (network.type()) {
+ case FLAT:
+ case VLAN:
+ initGatewayNodeBridge(network, true);
+ break;
+ case VXLAN:
+ case GRE:
+ case GENEVE:
+ default:
+ // do nothing
+ break;
+ }
}
}
}