Support inter-node routing for k8s passthrough use case
Change-Id: I64411d8b20c7d501603eda5cd44d0aa7c47c99c7
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 ecec966..3731936 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
@@ -88,6 +88,7 @@
public static final int PRIORITY_CT_DROP_RULE = 32500;
public static final int PRIORITY_NAT_RULE = 30000;
public static final int PRIORITY_GATEWAY_RULE = 31000;
+ public static final int PRIORITY_INTER_NODE_RULE = 33000;
public static final int PRIORITY_LOCAL_BRIDGE_RULE = 32000;
public static final int PRIORITY_SWITCHING_RULE = 30000;
public static final int PRIORITY_CIDR_RULE = 30000;
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 dde6828..3efe41b 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
@@ -15,6 +15,7 @@
*/
package org.onosproject.k8snetworking.impl;
+import org.apache.commons.lang.StringUtils;
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip4Address;
@@ -29,6 +30,8 @@
import org.onosproject.k8snetworking.api.K8sNetworkEvent;
import org.onosproject.k8snetworking.api.K8sNetworkListener;
import org.onosproject.k8snetworking.api.K8sNetworkService;
+import org.onosproject.k8snode.api.K8sHost;
+import org.onosproject.k8snode.api.K8sHostService;
import org.onosproject.k8snode.api.K8sNode;
import org.onosproject.k8snode.api.K8sNodeEvent;
import org.onosproject.k8snode.api.K8sNodeListener;
@@ -51,6 +54,7 @@
import org.slf4j.Logger;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.ExecutorService;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
@@ -62,6 +66,7 @@
import static org.onosproject.k8snetworking.api.Constants.LOCAL_ENTRY_TABLE;
import static org.onosproject.k8snetworking.api.Constants.PRIORITY_ARP_REPLY_RULE;
import static org.onosproject.k8snetworking.api.Constants.PRIORITY_GATEWAY_RULE;
+import static org.onosproject.k8snetworking.api.Constants.PRIORITY_INTER_NODE_RULE;
import static org.onosproject.k8snetworking.api.Constants.PRIORITY_LOCAL_BRIDGE_RULE;
import static org.onosproject.k8snetworking.api.Constants.ROUTING_TABLE;
import static org.onosproject.k8snetworking.api.Constants.SHIFTED_IP_PREFIX;
@@ -116,6 +121,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected K8sNodeService k8sNodeService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected K8sHostService k8sHostService;
+
private final ExecutorService eventExecutor = newSingleThreadExecutor(
groupedThreads(this.getClass().getSimpleName(), "event-handler"));
private final InternalK8sNetworkListener k8sNetworkListener =
@@ -218,6 +226,52 @@
}
}
+ private void setInterNodeRoutingRules(K8sNetwork k8sNetwork, boolean install) {
+ K8sNode srcNode = k8sNodeService.node(k8sNetwork.name());
+
+ if (srcNode == null) {
+ return;
+ }
+
+ for (K8sNode dstNode : k8sNodeService.completeNodes()) {
+ if (StringUtils.equals(srcNode.hostname(), dstNode.hostname())) {
+ continue;
+ }
+
+ boolean sameHost = false;
+ for (K8sHost host : k8sHostService.completeHosts()) {
+ Set<String> nodeNames = host.nodeNames();
+ // if the src and dst nodes located in the same hosts,
+ // we simply do not tunnel the traffic, instead we route the traffic
+ if (nodeNames.contains(srcNode.hostname()) &&
+ nodeNames.contains(dstNode.hostname())) {
+ sameHost = true;
+ }
+ }
+
+ if (sameHost) {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPSrc(IpPrefix.valueOf(srcNode.podCidr()))
+ .matchIPDst(IpPrefix.valueOf(dstNode.podCidr()))
+ .build();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setOutput(dstNode.tunToIntgPortNum())
+ .build();
+
+ k8sFlowRuleService.setRule(
+ appId,
+ dstNode.tunBridge(),
+ selector,
+ treatment,
+ PRIORITY_INTER_NODE_RULE,
+ TUN_ENTRY_TABLE,
+ install);
+ }
+ }
+ }
+
private void setLocalBridgeRules(K8sNetwork k8sNetwork, boolean install) {
for (K8sNode node : k8sNodeService.completeNodes()) {
if (node.hostname().equals(k8sNetwork.name())) {
@@ -338,6 +392,7 @@
setGatewayRule(event.subject(), true);
setLocalBridgeRules(event.subject(), true);
setLocalBridgeArpRules(event.subject(), true);
+ setInterNodeRoutingRules(event.subject(), true);
}
private void processNetworkRemoval(K8sNetworkEvent event) {
@@ -348,6 +403,7 @@
setGatewayRule(event.subject(), false);
setLocalBridgeRules(event.subject(), false);
setLocalBridgeArpRules(event.subject(), false);
+ setInterNodeRoutingRules(event.subject(), false);
}
}
@@ -378,6 +434,7 @@
k8sNetworkService.networks().forEach(n -> setGatewayRule(n, true));
k8sNetworkService.networks().forEach(n -> setLocalBridgeRules(n, true));
k8sNetworkService.networks().forEach(n -> setLocalBridgeArpRules(n, true));
+ k8sNetworkService.networks().forEach(n -> setInterNodeRoutingRules(n, true));
}
}
}