Split tunneling behavior into a separated tunnel bridge
Change-Id: I4de5f21ac9eaf286479f619c960a2319b597a819
diff --git a/apps/k8s-networking/api/src/main/java/org/onosproject/k8snetworking/api/Constants.java b/apps/k8s-networking/api/src/main/java/org/onosproject/k8snetworking/api/Constants.java
index 503ab08..3588414 100644
--- a/apps/k8s-networking/api/src/main/java/org/onosproject/k8snetworking/api/Constants.java
+++ b/apps/k8s-networking/api/src/main/java/org/onosproject/k8snetworking/api/Constants.java
@@ -95,6 +95,7 @@
public static final int PRIORITY_NODE_PORT_RULE = 42000;
public static final int PRIORITY_NODE_PORT_REMOTE_RULE = 41500;
public static final int PRIORITY_NODE_PORT_INTER_RULE = 40000;
+ public static final int PRIORITY_DEFAULT_RULE = 0;
// flow table index
public static final int STAT_INGRESS_TABLE = 0;
@@ -125,6 +126,8 @@
public static final int LOCAL_ENTRY_TABLE = 0;
+ public static final int TUN_ENTRY_TABLE = 0;
+
// CLI item length
public static final int CLI_ID_LENGTH = 30;
public static final int CLI_NAME_LENGTH = 30;
diff --git a/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sFlowRuleManager.java b/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sFlowRuleManager.java
index 73ce2ef..0234613 100644
--- a/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sFlowRuleManager.java
+++ b/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sFlowRuleManager.java
@@ -70,6 +70,7 @@
import static org.onosproject.k8snetworking.api.Constants.ROUTING_TABLE;
import static org.onosproject.k8snetworking.api.Constants.STAT_EGRESS_TABLE;
import static org.onosproject.k8snetworking.api.Constants.STAT_INGRESS_TABLE;
+import static org.onosproject.k8snetworking.api.Constants.TUN_ENTRY_TABLE;
import static org.onosproject.k8snetworking.api.Constants.VTAG_TABLE;
import static org.onosproject.k8snetworking.api.Constants.VTAP_EGRESS_TABLE;
import static org.onosproject.k8snetworking.api.Constants.VTAP_INGRESS_TABLE;
@@ -317,16 +318,32 @@
}
tBuilder.transition(STAT_EGRESS_TABLE);
} else {
+ K8sNode localNode = k8sNodeService.node(k8sNetwork.name());
+ tBuilder.setOutput(node.intgToTunPortNum());
+
+ // install flows into tunnel bridge
PortNumber portNum = tunnelPortNumByNetId(k8sNetwork.networkId(),
k8sNetworkService, node);
- K8sNode localNode = k8sNodeService.node(k8sNetwork.name());
+ TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
+ .extension(buildExtension(
+ deviceService,
+ node.tunBridge(),
+ localNode.dataIp().getIp4Address()),
+ node.tunBridge())
+ .setTunnelId(Long.valueOf(k8sNetwork.segmentId()))
+ .setOutput(portNum)
+ .build();
- tBuilder.extension(buildExtension(
- deviceService,
- node.intgBridge(),
- localNode.dataIp().getIp4Address()),
- node.intgBridge())
- .setOutput(portNum);
+ FlowRule remoteFlowRule = DefaultFlowRule.builder()
+ .forDevice(node.tunBridge())
+ .withSelector(sBuilder.build())
+ .withTreatment(treatmentToRemote)
+ .withPriority(PRIORITY_CIDR_RULE)
+ .fromApp(appId)
+ .makePermanent()
+ .forTable(TUN_ENTRY_TABLE)
+ .build();
+ applyRule(remoteFlowRule, true);
}
FlowRule flowRule = DefaultFlowRule.builder()
diff --git a/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sServiceHandler.java b/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sServiceHandler.java
index 18b9a11..fd0dff0 100644
--- a/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sServiceHandler.java
+++ b/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sServiceHandler.java
@@ -111,6 +111,7 @@
import static org.onosproject.k8snetworking.api.Constants.SHIFTED_IP_PREFIX;
import static org.onosproject.k8snetworking.api.Constants.SRC;
import static org.onosproject.k8snetworking.api.Constants.STAT_EGRESS_TABLE;
+import static org.onosproject.k8snetworking.api.Constants.TUN_ENTRY_TABLE;
import static org.onosproject.k8snetworking.impl.OsgiPropertyConstants.SERVICE_CIDR;
import static org.onosproject.k8snetworking.impl.OsgiPropertyConstants.SERVICE_IP_CIDR_DEFAULT;
import static org.onosproject.k8snetworking.impl.OsgiPropertyConstants.SERVICE_IP_NAT_MODE;
@@ -645,16 +646,33 @@
}
tBuilder.transition(STAT_EGRESS_TABLE);
} else {
- PortNumber portNum = tunnelPortNumByNetId(network.networkId(),
- k8sNetworkService, n);
K8sNode localNode = k8sNodeService.node(network.name());
- tBuilder.extension(buildExtension(
- deviceService,
- n.intgBridge(),
- localNode.dataIp().getIp4Address()),
- n.intgBridge())
- .setOutput(portNum);
+ tBuilder.setOutput(n.intgToTunPortNum());
+
+ PortNumber portNum = tunnelPortNumByNetId(network.networkId(),
+ k8sNetworkService, n);
+
+ // install rules into tunnel bridge
+ TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
+ .extension(buildExtension(
+ deviceService,
+ n.tunBridge(),
+ localNode.dataIp().getIp4Address()),
+ n.tunBridge())
+ .setTunnelId(Long.valueOf(network.segmentId()))
+ .setOutput(portNum)
+ .build();
+
+ k8sFlowRuleService.setRule(
+ appId,
+ n.tunBridge(),
+ sBuilder.build(),
+ treatmentToRemote,
+ PRIORITY_CIDR_RULE,
+ TUN_ENTRY_TABLE,
+ install
+ );
}
k8sFlowRuleService.setRule(
diff --git a/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sSwitchingGatewayHandler.java b/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sSwitchingGatewayHandler.java
index 2f994da..03a953e 100644
--- a/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sSwitchingGatewayHandler.java
+++ b/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sSwitchingGatewayHandler.java
@@ -67,6 +67,7 @@
import static org.onosproject.k8snetworking.api.Constants.SHIFTED_IP_PREFIX;
import static org.onosproject.k8snetworking.api.Constants.SHIFTED_LOCAL_IP_PREFIX;
import static org.onosproject.k8snetworking.api.Constants.SRC;
+import static org.onosproject.k8snetworking.api.Constants.TUN_ENTRY_TABLE;
import static org.onosproject.k8snetworking.util.K8sNetworkingUtil.shiftIpDomain;
import static org.onosproject.k8snetworking.util.K8sNetworkingUtil.tunnelPortNumByNetId;
import static org.onosproject.k8snetworking.util.RulePopulatorUtil.buildExtension;
@@ -159,16 +160,31 @@
tBuilder.setEthDst(node.intgBridgeMac())
.setOutput(PortNumber.LOCAL);
} else {
- PortNumber portNum = tunnelPortNumByNetId(k8sNetwork.networkId(),
- k8sNetworkService, node);
K8sNode localNode = k8sNodeService.node(k8sNetwork.name());
- tBuilder.extension(buildExtension(
- deviceService,
- node.intgBridge(),
- localNode.dataIp().getIp4Address()),
- node.intgBridge())
- .setOutput(portNum);
+ tBuilder.setOutput(node.intgToTunPortNum());
+
+ // install flows into tunnel bridge
+ PortNumber portNum = tunnelPortNumByNetId(k8sNetwork.networkId(),
+ k8sNetworkService, node);
+ TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
+ .extension(buildExtension(
+ deviceService,
+ node.tunBridge(),
+ localNode.dataIp().getIp4Address()),
+ node.tunBridge())
+ .setTunnelId(Long.valueOf(k8sNetwork.segmentId()))
+ .setOutput(portNum)
+ .build();
+
+ k8sFlowRuleService.setRule(
+ appId,
+ node.tunBridge(),
+ sBuilder.build(),
+ treatmentToRemote,
+ PRIORITY_GATEWAY_RULE,
+ TUN_ENTRY_TABLE,
+ install);
}
k8sFlowRuleService.setRule(
diff --git a/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sSwitchingHandler.java b/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sSwitchingHandler.java
index 56c4398..0165975 100644
--- a/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sSwitchingHandler.java
+++ b/apps/k8s-networking/app/src/main/java/org/onosproject/k8snetworking/impl/K8sSwitchingHandler.java
@@ -61,8 +61,10 @@
import static org.onosproject.k8snetworking.api.Constants.FORWARDING_TABLE;
import static org.onosproject.k8snetworking.api.Constants.JUMP_TABLE;
import static org.onosproject.k8snetworking.api.Constants.K8S_NETWORKING_APP_ID;
+import static org.onosproject.k8snetworking.api.Constants.PRIORITY_DEFAULT_RULE;
import static org.onosproject.k8snetworking.api.Constants.PRIORITY_SWITCHING_RULE;
import static org.onosproject.k8snetworking.api.Constants.PRIORITY_TUNNEL_TAG_RULE;
+import static org.onosproject.k8snetworking.api.Constants.TUN_ENTRY_TABLE;
import static org.onosproject.k8snetworking.api.Constants.VTAG_TABLE;
import static org.onosproject.k8snetworking.util.K8sNetworkingUtil.getPropertyValue;
import static org.onosproject.k8snetworking.util.K8sNetworkingUtil.tunnelPortNumByNetId;
@@ -150,7 +152,7 @@
/**
* Configures the flow rules which are used for L2 packet switching.
- * Note that these rules will be inserted in switching table (table 5).
+ * Note that these rules will be inserted in switching table (table 80).
*
* @param port kubernetes port object
* @param install install flag, add the rule if true, remove it otherwise
@@ -161,7 +163,7 @@
// TODO: need to handle IPv6 in near future
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPDst(port.ipAddress().toIpPrefix())
- .matchTunnelId(getVni(port))
+ // .matchTunnelId(getVni(port))
.build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
@@ -188,28 +190,86 @@
k8sNodeService.completeNodes().stream()
.filter(remoteNode -> !remoteNode.intgBridge().equals(localNode.intgBridge()))
.forEach(remoteNode -> {
- PortNumber portNum = tunnelPortNumByNetId(port.networkId(),
- k8sNetworkService, remoteNode);
- TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
- .extension(buildExtension(
- deviceService,
- remoteNode.intgBridge(),
- localNode.dataIp().getIp4Address()),
- remoteNode.intgBridge())
- .setOutput(portNum)
+ TrafficTreatment treatmentToTunnel = DefaultTrafficTreatment.builder()
+ .setOutput(remoteNode.intgToTunPortNum())
.build();
k8sFlowRuleService.setRule(
appId,
remoteNode.intgBridge(),
selector,
- treatmentToRemote,
+ treatmentToTunnel,
PRIORITY_SWITCHING_RULE,
FORWARDING_TABLE,
install);
+
+ PortNumber portNum = tunnelPortNumByNetId(port.networkId(),
+ k8sNetworkService, remoteNode);
+
+ TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder()
+ .extension(buildExtension(
+ deviceService,
+ remoteNode.tunBridge(),
+ localNode.dataIp().getIp4Address()),
+ remoteNode.tunBridge())
+ .setTunnelId(getVni(port))
+ .setOutput(portNum)
+ .build();
+
+ k8sFlowRuleService.setRule(
+ appId,
+ remoteNode.tunBridge(),
+ selector,
+ treatmentToRemote,
+ PRIORITY_DEFAULT_RULE,
+ TUN_ENTRY_TABLE,
+ install);
});
}
+ private void setRulesForTunnelBridge(K8sNode node, boolean install) {
+ setRulesForTunnelBridgeByType(node, K8sNetwork.Type.VXLAN, install);
+ setRulesForTunnelBridgeByType(node, K8sNetwork.Type.GRE, install);
+ setRulesForTunnelBridgeByType(node, K8sNetwork.Type.GENEVE, install);
+ }
+
+ private void setRulesForTunnelBridgeByType(K8sNode node, K8sNetwork.Type type, boolean install) {
+
+ PortNumber portNum;
+
+ switch (type) {
+ case VXLAN:
+ portNum = node.vxlanPortNum();
+ break;
+ case GRE:
+ portNum = node.grePortNum();
+ break;
+ case GENEVE:
+ portNum = node.genevePortNum();
+ break;
+ default:
+ return;
+ }
+
+ TrafficSelector inboundSelector = DefaultTrafficSelector.builder()
+ .matchInPort(portNum)
+ .build();
+
+ TrafficTreatment inboundTreatment = DefaultTrafficTreatment.builder()
+ .setOutput(node.tunToIntgPortNum())
+ .build();
+
+ k8sFlowRuleService.setRule(
+ appId,
+ node.tunBridge(),
+ inboundSelector,
+ inboundTreatment,
+ PRIORITY_DEFAULT_RULE,
+ TUN_ENTRY_TABLE,
+ install);
+ }
+
+
private void setTunnelTagArpFlowRules(K8sPort port, boolean install) {
setTunnelTagFlowRules(port, Ethernet.TYPE_ARP, install);
}
@@ -439,6 +499,7 @@
setExtToIntgTunnelTagFlowRules(k8sNode, true);
setLocalTunnelTagFlowRules(k8sNode, true);
+ setRulesForTunnelBridge(k8sNode, true);
}
}
}
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java
index 56039b5..4e430a3 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java
@@ -396,6 +396,16 @@
}
@Override
+ public PortNumber intgToTunPortNum() {
+ return portNumber(intgBridge, intgToTunPatchPortName());
+ }
+
+ @Override
+ public PortNumber tunToIntgPortNum() {
+ return portNumber(tunBridge, tunToIntgPatchPortName());
+ }
+
+ @Override
public PortNumber extBridgePortNum() {
if (this.extIntf == null) {
return null;
@@ -519,6 +529,15 @@
}
@Override
+ public String tunBridgePortName() {
+ if (mode == PASSTHROUGH) {
+ return TUNNEL_BRIDGE + "-" + uniqueString(5);
+ } else {
+ return TUNNEL_BRIDGE;
+ }
+ }
+
+ @Override
public String intgToExtPatchPortName() {
if (mode == PASSTHROUGH) {
return INTEGRATION_TO_EXTERNAL_BRIDGE + "-" + uniqueString(5);
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java
index 8931b45..e443880 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java
@@ -287,6 +287,13 @@
String localBridgePortName();
/**
+ * Returns tunnel bridge port name.
+ *
+ * @return tunnel bridge port name
+ */
+ String tunBridgePortName();
+
+ /**
* Returns integration to external patch port name.
*
* @return integration to external patch port name
@@ -385,6 +392,20 @@
PortNumber extToIntgPatchPortNum();
/**
+ * Returns the integration to tunnel patch port number.
+ *
+ * @return patch port number
+ */
+ PortNumber intgToTunPortNum();
+
+ /**
+ * Returns the tunnel to integration patch port number.
+ *
+ * @return patch port number
+ */
+ PortNumber tunToIntgPortNum();
+
+ /**
* Returns the external bridge to router port number.
*
* @return port number, null if the port does not exist
diff --git a/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/cli/K8sNodeCheckCommand.java b/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/cli/K8sNodeCheckCommand.java
index 2060712..de8f38c 100644
--- a/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/cli/K8sNodeCheckCommand.java
+++ b/apps/k8s-node/app/src/main/java/org/onosproject/k8snode/cli/K8sNodeCheckCommand.java
@@ -68,11 +68,6 @@
printPortState(deviceService, node.intgBridge(), node.intgBridgePortName());
printPortState(deviceService, node.intgBridge(), node.intgToExtPatchPortName());
printPortState(deviceService, node.intgBridge(), node.intgToLocalPatchPortName());
- if (node.dataIp() != null) {
- printPortState(deviceService, node.intgBridge(), node.vxlanPortName());
- printPortState(deviceService, node.intgBridge(), node.grePortName());
- printPortState(deviceService, node.intgBridge(), node.genevePortName());
- }
} else {
print("%s %s=%s is not available",
MSG_ERROR,
@@ -80,6 +75,7 @@
node.intgBridge());
}
+ print("");
print("[External Bridge Status]");
Device extBridge = deviceService.getDevice(node.extBridge());
if (extBridge != null) {
@@ -89,7 +85,6 @@
extBridge.id(),
deviceService.isAvailable(extBridge.id()),
extBridge.annotations());
- printPortState(deviceService, node.extBridge(), node.extBridgePortName());
printPortState(deviceService, node.extBridge(), node.extToIntgPatchPortName());
} else {
print("%s %s=%s is not available",
@@ -98,6 +93,7 @@
node.extBridge());
}
+ print("");
print("[Local Bridge Status]");
Device localBridge = deviceService.getDevice(node.localBridge());
if (localBridge != null) {
@@ -107,9 +103,27 @@
localBridge.id(),
deviceService.isAvailable(localBridge.id()),
localBridge.annotations());
- printPortState(deviceService, node.localBridge(), node.localBridgePortName());
printPortState(deviceService, node.localBridge(), node.localToIntgPatchPortName());
}
+
+ print("");
+ print("[Tunnel Bridge Status]");
+ Device tunBridge = deviceService.getDevice(node.tunBridge());
+ if (tunBridge != null) {
+ print("%s %s=%s available=%s %s",
+ deviceService.isAvailable(tunBridge.id()) ? MSG_OK : MSG_ERROR,
+ node.tunBridgeName(),
+ tunBridge.id(),
+ deviceService.isAvailable(tunBridge.id()),
+ tunBridge.annotations());
+ printPortState(deviceService, node.tunBridge(), node.tunToIntgPatchPortName());
+
+ if (node.dataIp() != null) {
+ printPortState(deviceService, node.tunBridge(), node.vxlanPortName());
+ printPortState(deviceService, node.tunBridge(), node.grePortName());
+ printPortState(deviceService, node.tunBridge(), node.genevePortName());
+ }
+ }
}
private void printPortState(DeviceService deviceService,