Support LB in kubevirt networking application.
Change-Id: I59578fc0b778173a20c958b641cf9bf1abe69bc6
(cherry picked from commit c8a8759e3adc292a429a4ca7173d15c220b7ea3c)
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java
index 04ac0c8..c6a9179 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java
@@ -68,6 +68,7 @@
public static final int PRIORITY_ICMP_RULE = 43000;
public static final int PRIORITY_FORWARDING_RULE = 30000;
public static final int PRIORITY_FLOATING_GATEWAY_TUN_BRIDGE_RULE = 32000;
+ public static final int PRIORITY_LB_GATEWAY_TUN_BRIDGE_RULE = 33000;
public static final int PRIORITY_DHCP_RULE = 42000;
public static final int PRIORITY_ARP_GATEWAY_RULE = 41000;
public static final int PRIORITY_ARP_DEFAULT_RULE = 40000;
@@ -104,4 +105,6 @@
public static final int PRIORITY_STATEFUL_SNAT_RULE = 40500;
public static final int PRIORITY_FLOATING_IP_RULE = 40800;
public static final int PRIORITY_INTERNAL_ROUTING_RULE = 41000;
+ public static final int PRIORITY_LB_RULE = 41500;
+ public static final int PRIORITY_LB_FIP_RULE = 41500;
}
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtLoadBalancerRule.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtLoadBalancerRule.java
index 453610e..bd2f64a 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtLoadBalancerRule.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtLoadBalancerRule.java
@@ -26,6 +26,7 @@
*/
public final class DefaultKubevirtLoadBalancerRule implements KubevirtLoadBalancerRule {
private static final String NOT_NULL_MSG = "Load Balancer Rule % cannot be null";
+ private static final String ICMP = "ICMP";
private final String protocol;
private final Integer portRangeMax;
@@ -70,9 +71,10 @@
return false;
}
DefaultKubevirtLoadBalancerRule that = (DefaultKubevirtLoadBalancerRule) o;
+
return protocol.equals(that.protocol) &&
- portRangeMax.equals(that.portRangeMax) &&
- portRangeMin.equals(that.portRangeMin);
+ Objects.equals(portRangeMax, that.portRangeMax) &&
+ Objects.equals(portRangeMin, that.portRangeMin);
}
@Override
@@ -107,9 +109,11 @@
@Override
public KubevirtLoadBalancerRule build() {
checkArgument(protocol != null, NOT_NULL_MSG, "protocol");
- checkArgument(portRangeMax != null, NOT_NULL_MSG, "portRangeMax");
- checkArgument(portRangeMin != null, NOT_NULL_MSG, "portRangeMin");
+ if (!protocol.equalsIgnoreCase(ICMP)) {
+ checkArgument(portRangeMax != null, NOT_NULL_MSG, "portRangeMax");
+ checkArgument(portRangeMin != null, NOT_NULL_MSG, "portRangeMin");
+ }
return new DefaultKubevirtLoadBalancerRule(protocol, portRangeMax, portRangeMin);
}
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtGroupRuleService.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtGroupRuleService.java
new file mode 100644
index 0000000..9d54fd3
--- /dev/null
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtGroupRuleService.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.kubevirtnetworking.api;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupDescription;
+
+import java.util.List;
+
+/**
+ * Service for setting group rules.
+ */
+public interface KubevirtGroupRuleService {
+
+ /**
+ * Configures the group table rule.
+ *
+ * @param appId application ID
+ * @param deviceId device ID
+ * @param groupId group ID
+ * @param type group type
+ * @param buckets a list of group buckets
+ * @param install true for rule addition, false for rule removal
+ */
+ void setRule(ApplicationId appId, DeviceId deviceId, int groupId,
+ GroupDescription.Type type, List<GroupBucket> buckets, boolean install);
+
+ /**
+ * Checks whether has the group in store with given device ID and group ID.
+ *
+ * @param deviceId device ID
+ * @param groupId group ID
+ * @return true if the group exists, false otherwise
+ */
+ boolean hasGroup(DeviceId deviceId, int groupId);
+
+ /**
+ * Configures buckets to the existing group.
+ * With install flag true, this method will add buckets to existing buckets,
+ * while with install flag false, this method will remove buckets from
+ * existing buckets.
+ *
+ * @param appId application ID
+ * @param deviceId device ID
+ * @param groupId group ID
+ * @param buckets a list of group buckets
+ * @param install true for buckets addition, false for buckets removal
+ */
+ void setBuckets(ApplicationId appId, DeviceId deviceId, int groupId,
+ List<GroupBucket> buckets, boolean install);
+
+ /**
+ * Configures buckets.
+ *
+ * @param appId application ID
+ * @param deviceId device ID
+ * @param groupId group ID
+ * @param buckets a lit of group buckets
+ */
+ void setBuckets(ApplicationId appId, DeviceId deviceId, int groupId,
+ List<GroupBucket> buckets);
+}
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtLoadBalancerEvent.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtLoadBalancerEvent.java
index ad09091..e80d1a7 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtLoadBalancerEvent.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtLoadBalancerEvent.java
@@ -15,11 +15,17 @@
*/
package org.onosproject.kubevirtnetworking.api;
+import org.onlab.packet.IpAddress;
import org.onosproject.event.AbstractEvent;
+import java.util.Set;
+
public class KubevirtLoadBalancerEvent
extends AbstractEvent<KubevirtLoadBalancerEvent.Type, KubevirtLoadBalancer> {
+ private final KubevirtLoadBalancer old;
+ private final Set<IpAddress> members;
+
/**
* LoadBalancerEvent constructor.
*
@@ -28,6 +34,52 @@
*/
public KubevirtLoadBalancerEvent(Type type, KubevirtLoadBalancer lb) {
super(type, lb);
+ this.old = null;
+ this.members = null;
+ }
+
+ /**
+ * Creates and event of a given type for the specified kubevirt loadbalancer.
+ *
+ * @param type kubevirt loadbalancer event type
+ * @param lb kubevirt loadbalancer
+ * @param old old kubevirt loadbalancer
+ */
+ public KubevirtLoadBalancerEvent(Type type, KubevirtLoadBalancer lb, KubevirtLoadBalancer old) {
+ super(type, lb);
+ this.old = old;
+ this.members = null;
+ }
+
+ /**
+ * Creates and event of a given type for the specified kubevirt loadbalancer.
+ *
+ * @param type kubevirt loadbalancer event type
+ * @param lb kubevirt loadbalancer
+ * @param members kubevirt loadbalancer members
+ */
+ public KubevirtLoadBalancerEvent(Type type, KubevirtLoadBalancer lb, Set<IpAddress> members) {
+ super(type, lb);
+ this.old = null;
+ this.members = members;
+ }
+
+ /**
+ * Returns the old kubevirt loadbalancer of the event.
+ *
+ * @return old kubevirt loadbalancer
+ */
+ public KubevirtLoadBalancer oldLb() {
+ return old;
+ }
+
+ /**
+ * Returns members of kubevirt loadbalancer of the event.
+ *
+ * @return kubevirt loadbalancer members
+ */
+ public Set<IpAddress> members() {
+ return members;
}
public enum Type {
@@ -37,13 +89,23 @@
KUBEVIRT_LOAD_BALANCER_CREATED,
/**
- * Signifies that a new kubevirt load balancer is removed.
+ * Signifies that a kubevirt load balancer is removed.
*/
KUBEVIRT_LOAD_BALANCER_REMOVED,
/**
- * Signifies that a new kubevirt load balancer is updated.
+ * Signifies that a kubevirt load balancer is updated.
*/
KUBEVIRT_LOAD_BALANCER_UPDATED,
+
+ /**
+ * Signifies that a kubevirt load balancer member is added.
+ */
+ KUBEVIRT_LOAD_BALANCER_MEMBER_ADDED,
+
+ /**
+ * Signifies that a kubevirt load balancer member is added.
+ */
+ KUBEVIRT_LOAD_BALANCER_MEMBER_REMOVED,
}
}
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterEvent.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterEvent.java
index ccd927d..4cd31eb 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterEvent.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterEvent.java
@@ -225,7 +225,19 @@
/**
* Signified that the snat status disabled for this router.
*/
- KUBEVIRT_SNAT_STATUS_DISABLED
+ KUBEVIRT_SNAT_STATUS_DISABLED,
+ /**
+ * Signifies that the floating IP is associated to a lb VIP.
+ */
+ KUBEVIRT_FLOATING_IP_LB_ASSOCIATED,
+ /**
+ * Signifies that the floating IP is disassociated to a lb VIP.
+ */
+ KUBEVIRT_FLOATING_IP_LB_DISASSOCIATED,
+ /**
+ * Signifies the that peer router mac address is retrieved for this router.
+ */
+ KUBEVIRT_PEER_ROUTER_MAC_RETRIEVED,
}
/**
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/codec/KubevirtLoadBalancerRuleCodec.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/codec/KubevirtLoadBalancerRuleCodec.java
index 8977284..613ac10 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/codec/KubevirtLoadBalancerRuleCodec.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/codec/KubevirtLoadBalancerRuleCodec.java
@@ -36,6 +36,7 @@
private static final String PROTOCOL = "protocol";
private static final String PORT_RANGE_MAX = "portRangeMax";
private static final String PORT_RANGE_MIN = "portRangeMin";
+ private static final String ICMP = "ICMP";
private static final String MISSING_MESSAGE = " is required in KubevirtLoadBalancerRule";
@@ -43,10 +44,12 @@
public ObjectNode encode(KubevirtLoadBalancerRule rule, CodecContext context) {
checkNotNull(rule, "Kubevirt load balancer rule cannot be null");
- return context.mapper().createObjectNode()
- .put(PROTOCOL, rule.protocol())
- .put(PORT_RANGE_MAX, rule.portRangeMax())
- .put(PORT_RANGE_MIN, rule.portRangeMin());
+ ObjectNode result = context.mapper().createObjectNode().put(PROTOCOL, rule.protocol());
+
+ if (!rule.protocol().equalsIgnoreCase(ICMP)) {
+ result.put(PORT_RANGE_MAX, rule.portRangeMax()).put(PORT_RANGE_MIN, rule.portRangeMin());
+ }
+ return result;
}
@Override
@@ -55,14 +58,18 @@
return null;
}
- String protocol = nullIsIllegal(json.get(PROTOCOL).asText(), PROTOCOL + MISSING_MESSAGE);
- Integer portRangeMax = json.get(PORT_RANGE_MAX).asInt();
- Integer portRangeMin = json.get(PORT_RANGE_MIN).asInt();
+ KubevirtLoadBalancerRule.Builder builder = DefaultKubevirtLoadBalancerRule.builder();
- return DefaultKubevirtLoadBalancerRule.builder()
- .protocol(protocol)
- .portRangeMax(portRangeMax)
- .portRangeMin(portRangeMin)
- .build();
+ String protocol = nullIsIllegal(json.get(PROTOCOL).asText(), PROTOCOL + MISSING_MESSAGE);
+
+ builder.protocol(protocol);
+
+ if (!protocol.equalsIgnoreCase(ICMP)) {
+ Integer portRangeMax = json.get(PORT_RANGE_MAX).asInt();
+ Integer portRangeMin = json.get(PORT_RANGE_MIN).asInt();
+ builder.portRangeMax(portRangeMax).portRangeMin(portRangeMin);
+ }
+
+ return builder.build();
}
}
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtLoadBalancerStore.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtLoadBalancerStore.java
index fd90e8a..1c045f3 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtLoadBalancerStore.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtLoadBalancerStore.java
@@ -16,6 +16,7 @@
package org.onosproject.kubevirtnetworking.impl;
import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.IpAddress;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
@@ -42,6 +43,7 @@
import org.slf4j.Logger;
import java.util.Collection;
+import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
@@ -49,6 +51,8 @@
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancerEvent.Type.KUBEVIRT_LOAD_BALANCER_CREATED;
+import static org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancerEvent.Type.KUBEVIRT_LOAD_BALANCER_MEMBER_ADDED;
+import static org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancerEvent.Type.KUBEVIRT_LOAD_BALANCER_MEMBER_REMOVED;
import static org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancerEvent.Type.KUBEVIRT_LOAD_BALANCER_REMOVED;
import static org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancerEvent.Type.KUBEVIRT_LOAD_BALANCER_UPDATED;
import static org.slf4j.LoggerFactory.getLogger;
@@ -168,9 +172,7 @@
break;
case UPDATE:
log.debug("Kubevirt load balancer updated");
- eventExecutor.execute(() ->
- notifyDelegate(new KubevirtLoadBalancerEvent(
- KUBEVIRT_LOAD_BALANCER_UPDATED, event.newValue().value())));
+ eventExecutor.execute(() -> processLoadBalancerMapUpdate(event));
break;
case REMOVE:
log.debug("Kubevirt load balancer removed");
@@ -183,5 +185,41 @@
break;
}
}
+
+ private void processLoadBalancerMapUpdate(MapEvent<String, KubevirtLoadBalancer> event) {
+ KubevirtLoadBalancer oldLb = event.oldValue().value();
+ KubevirtLoadBalancer newLb = event.newValue().value();
+
+ Set<IpAddress> added = new HashSet<>(newLb.members());
+ Set<IpAddress> oldSet = oldLb.members();
+
+ added.removeAll(oldSet);
+
+ if (added.size() > 0) {
+ notifyDelegate(new KubevirtLoadBalancerEvent(
+ KUBEVIRT_LOAD_BALANCER_MEMBER_ADDED,
+ newLb,
+ added
+ ));
+ }
+
+ Set<IpAddress> removed = new HashSet<>(oldLb.members());
+ Set<IpAddress> newSet = newLb.members();
+ removed.removeAll(newSet);
+
+ if (removed.size() > 0) {
+ notifyDelegate(new KubevirtLoadBalancerEvent(
+ KUBEVIRT_LOAD_BALANCER_MEMBER_REMOVED,
+ newLb,
+ removed
+ ));
+ }
+
+ notifyDelegate(new KubevirtLoadBalancerEvent(
+ KUBEVIRT_LOAD_BALANCER_UPDATED,
+ newLb,
+ oldLb
+ ));
+ }
}
}
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtRouterStore.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtRouterStore.java
index 626d2eb..9248f06 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtRouterStore.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/DistributedKubevirtRouterStore.java
@@ -17,12 +17,15 @@
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.IpAddress;
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.kubevirtnetworking.api.DefaultKubevirtFloatingIp;
import org.onosproject.kubevirtnetworking.api.DefaultKubevirtRouter;
import org.onosproject.kubevirtnetworking.api.KubevirtFloatingIp;
+import org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancer;
+import org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancerService;
import org.onosproject.kubevirtnetworking.api.KubevirtPeerRouter;
import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
import org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent;
@@ -55,11 +58,14 @@
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_ASSOCIATED;
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_CREATED;
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_DISASSOCIATED;
+import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_LB_ASSOCIATED;
+import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_LB_DISASSOCIATED;
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_REMOVED;
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_FLOATING_IP_UPDATED;
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_GATEWAY_NODE_ATTACHED;
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_GATEWAY_NODE_CHANGED;
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_GATEWAY_NODE_DETACHED;
+import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_PEER_ROUTER_MAC_RETRIEVED;
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_CREATED;
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_EXTERNAL_NETWORK_ATTACHED;
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_EXTERNAL_NETWORK_DETACHED;
@@ -68,6 +74,7 @@
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_REMOVED;
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_ROUTER_UPDATED;
import static org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent.Type.KUBEVIRT_SNAT_STATUS_DISABLED;
+import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getLoadBalancerSetForRouter;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -85,6 +92,8 @@
private static final String MSG_FLOATING_IP = "Kubevirt floating IP %s %s with %s";
private static final String MSG_ASSOCIATED = "associated";
private static final String MSG_DISASSOCIATED = "disassociated";
+ private static final String MSG_ASSOCIATED_LB = "associated LB VIP";
+ private static final String MSG_DISASSOCIATED_LB = "disassociated LB VIP";
private static final String APP_ID = "org.onosproject.kubevirtnetwork";
@@ -105,6 +114,9 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY)
protected StorageService storageService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected KubevirtLoadBalancerService loadBalancerService;
+
private final ExecutorService eventExecutor = newSingleThreadExecutor(
groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
@@ -265,6 +277,15 @@
KubevirtRouter oldValue = event.oldValue().value();
KubevirtRouter newValue = event.newValue().value();
+ if (oldValue.peerRouter() != null
+ && oldValue.peerRouter().macAddress() == null
+ && newValue.peerRouter() != null
+ && newValue.peerRouter().macAddress() != null) {
+ notifyDelegate(new KubevirtRouterEvent(
+ KUBEVIRT_PEER_ROUTER_MAC_RETRIEVED,
+ event.newValue().value()));
+ }
+
if (oldValue.external().size() == 0 && newValue.external().size() > 0) {
newValue.external().entrySet().stream().findAny()
.ifPresent(entry ->
@@ -411,6 +432,38 @@
log.info(String.format(MSG_FLOATING_IP,
event.newValue().value().floatingIp(), MSG_DISASSOCIATED, oldPodName));
}
+
+ IpAddress oldFixedIp = event.oldValue().value().fixedIp();
+ IpAddress newFixedIp = event.newValue().value().fixedIp();
+
+ getLoadBalancerSetForRouter(router, loadBalancerService)
+ .stream()
+ .map(KubevirtLoadBalancer::vip)
+ .forEach(vip -> {
+ if (oldFixedIp == null
+ && newFixedIp != null
+ && newFixedIp.equals(vip)) {
+ notifyDelegate(new KubevirtRouterEvent(
+ KUBEVIRT_FLOATING_IP_LB_ASSOCIATED,
+ router,
+ event.newValue().value()));
+ log.info(String.format(MSG_FLOATING_IP,
+ event.newValue().value().floatingIp(), MSG_ASSOCIATED_LB,
+ event.newValue().value().fixedIp()));
+ }
+
+ if (oldFixedIp != null
+ && newFixedIp == null
+ && oldFixedIp.equals(vip)) {
+ notifyDelegate(new KubevirtRouterEvent(
+ KUBEVIRT_FLOATING_IP_LB_DISASSOCIATED,
+ router,
+ event.oldValue().value()));
+ log.info(String.format(MSG_FLOATING_IP,
+ event.oldValue().value().floatingIp(), MSG_DISASSOCIATED_LB,
+ event.oldValue().value().fixedIp()));
+ }
+ });
}
}
}
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFloatingIpHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFloatingIpHandler.java
index cf8a877..ed086ae 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFloatingIpHandler.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFloatingIpHandler.java
@@ -338,8 +338,6 @@
KubevirtPort kubevirtPort = getKubevirtPort(floatingIp);
if (kubevirtPort == null) {
- log.warn("Failed to install floating Ip rules for floating ip {} " +
- "because there's no kubevirt port associated to it", floatingIp.floatingIp());
return;
}
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtGroupRuleManager.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtGroupRuleManager.java
new file mode 100644
index 0000000..60c2a6a
--- /dev/null
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtGroupRuleManager.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.kubevirtnetworking.impl;
+
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.kubevirtnetworking.api.KubevirtGroupRuleService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.group.DefaultGroupDescription;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+import org.onosproject.net.group.GroupDescription;
+import org.onosproject.net.group.GroupService;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.util.List;
+
+import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getGroupKey;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Sets group table rules directly using GroupService.
+ */
+@Component(immediate = true, service = KubevirtGroupRuleService.class)
+public class KubevirtGroupRuleManager implements KubevirtGroupRuleService {
+
+ private final Logger log = getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected GroupService groupService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected CoreService coreService;
+
+ @Activate
+ protected void activate() {
+ log.info("Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ log.info("Stopped");
+ }
+
+ @Override
+ public void setRule(ApplicationId appId, DeviceId deviceId, int groupId,
+ GroupDescription.Type type, List<GroupBucket> buckets,
+ boolean install) {
+ Group group = groupService.getGroup(deviceId, getGroupKey(groupId));
+ if (install) {
+ if (group == null) {
+ GroupDescription groupDesc = new DefaultGroupDescription(deviceId,
+ type, new GroupBuckets(buckets), getGroupKey(groupId), groupId, appId);
+ groupService.addGroup(groupDesc);
+ log.debug("Adding group table rule {}", groupId);
+ }
+ } else {
+ if (group != null) {
+ groupService.removeGroup(deviceId, getGroupKey(groupId), appId);
+ log.debug("Removing group table rule {}", groupId);
+ }
+ }
+ }
+
+ @Override
+ public boolean hasGroup(DeviceId deviceId, int groupId) {
+ return groupService.getGroup(deviceId, getGroupKey(groupId)) != null;
+ }
+
+ @Override
+ public void setBuckets(ApplicationId appId, DeviceId deviceId,
+ int groupId, List<GroupBucket> buckets, boolean install) {
+ if (!hasGroup(deviceId, groupId)) {
+ return;
+ }
+ if (install) {
+ // we add the buckets into the group, only if the buckets do not exist
+ // in the given group
+ Group group = groupService.getGroup(deviceId, getGroupKey(groupId));
+ if (group.buckets() != null && !group.buckets().buckets().containsAll(buckets)) {
+ groupService.addBucketsToGroup(deviceId, getGroupKey(groupId),
+ new GroupBuckets(buckets), getGroupKey(groupId), appId);
+ log.debug("Adding buckets for group rule {}", groupId);
+ }
+ } else {
+ groupService.removeBucketsFromGroup(deviceId, getGroupKey(groupId),
+ new GroupBuckets(buckets), getGroupKey(groupId), appId);
+ log.debug("Removing buckets for group rule {}", groupId);
+ }
+ }
+
+ @Override
+ public void setBuckets(ApplicationId appId, DeviceId deviceId,
+ int groupId, List<GroupBucket> buckets) {
+ groupService.setBucketsForGroup(deviceId, getGroupKey(groupId),
+ new GroupBuckets(buckets), getGroupKey(groupId), appId);
+ }
+}
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtLbHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtLbHandler.java
new file mode 100644
index 0000000..ba352eb
--- /dev/null
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtLbHandler.java
@@ -0,0 +1,815 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.kubevirtnetworking.impl;
+
+import com.google.common.collect.Lists;
+import org.onlab.packet.ARP;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.TpPort;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.GroupId;
+import org.onosproject.kubevirtnetworking.api.KubevirtFloatingIp;
+import org.onosproject.kubevirtnetworking.api.KubevirtFlowRuleService;
+import org.onosproject.kubevirtnetworking.api.KubevirtGroupRuleService;
+import org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancer;
+import org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancerEvent;
+import org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancerListener;
+import org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancerService;
+import org.onosproject.kubevirtnetworking.api.KubevirtNetwork;
+import org.onosproject.kubevirtnetworking.api.KubevirtNetworkService;
+import org.onosproject.kubevirtnetworking.api.KubevirtPort;
+import org.onosproject.kubevirtnetworking.api.KubevirtPortService;
+import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
+import org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent;
+import org.onosproject.kubevirtnetworking.api.KubevirtRouterListener;
+import org.onosproject.kubevirtnetworking.api.KubevirtRouterService;
+import org.onosproject.kubevirtnetworking.util.RulePopulatorUtil;
+import org.onosproject.kubevirtnode.api.KubevirtNode;
+import org.onosproject.kubevirtnode.api.KubevirtNodeService;
+import org.onosproject.net.Device;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.PacketService;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.slf4j.Logger;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.kubevirtnetworking.api.Constants.DEFAULT_GATEWAY_MAC;
+import static org.onosproject.kubevirtnetworking.api.Constants.GW_DROP_TABLE;
+import static org.onosproject.kubevirtnetworking.api.Constants.GW_ENTRY_TABLE;
+import static org.onosproject.kubevirtnetworking.api.Constants.KUBEVIRT_NETWORKING_APP_ID;
+import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_ARP_GATEWAY_RULE;
+import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_LB_GATEWAY_TUN_BRIDGE_RULE;
+import static org.onosproject.kubevirtnetworking.api.Constants.PRIORITY_LB_RULE;
+import static org.onosproject.kubevirtnetworking.api.Constants.TUNNEL_DEFAULT_TABLE;
+import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.GENEVE;
+import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.GRE;
+import static org.onosproject.kubevirtnetworking.api.KubevirtNetwork.Type.VXLAN;
+import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.buildGarpPacket;
+import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.externalPatchPortNum;
+import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getLoadBalancerSetForRouter;
+import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.getRouterForKubevirtNetwork;
+import static org.onosproject.kubevirtnetworking.util.KubevirtNetworkingUtil.tunnelPort;
+import static org.onosproject.kubevirtnetworking.util.RulePopulatorUtil.buildExtension;
+import static org.onosproject.net.group.GroupDescription.Type.SELECT;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Handles kubevirt loadbalancer.
+ */
+@Component(immediate = true)
+public class KubevirtLbHandler {
+ protected final Logger log = getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected ClusterService clusterService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected LeadershipService leadershipService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected DriverService driverService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected DeviceService deviceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected PacketService packetService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected KubevirtRouterService routerService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected KubevirtNetworkService networkService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected KubevirtGroupRuleService groupRuleService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected KubevirtNodeService nodeService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected KubevirtPortService portService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected KubevirtLoadBalancerService loadBalancerService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY)
+ protected KubevirtFlowRuleService flowRuleService;
+
+ private final InternalLbEventListener lbEventListener =
+ new InternalLbEventListener();
+
+ private final ExecutorService eventExecutor = newSingleThreadExecutor(
+ groupedThreads(this.getClass().getSimpleName(), "event-handler"));
+
+ private ApplicationId appId;
+ private NodeId localNodeId;
+
+ private static final String PROTOCOL_TCP = "TCP";
+ private static final String PROTOCOL_UDP = "UDP";
+ private static final String PROTOCOL_ICMP = "ICMP";
+
+ private final InternalRouterEventListener kubevirtRouterlistener = new InternalRouterEventListener();
+
+ @Activate
+ protected void activate() {
+ appId = coreService.registerApplication(KUBEVIRT_NETWORKING_APP_ID);
+ localNodeId = clusterService.getLocalNode().id();
+ leadershipService.runForLeadership(appId.name());
+
+ loadBalancerService.addListener(lbEventListener);
+ routerService.addListener(kubevirtRouterlistener);
+
+
+ log.info("Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ leadershipService.withdraw(appId.name());
+
+ loadBalancerService.removeListener(lbEventListener);
+ routerService.removeListener(kubevirtRouterlistener);
+
+ eventExecutor.shutdown();
+
+ log.info("Stopped");
+ }
+
+ private class InternalLbEventListener implements KubevirtLoadBalancerListener {
+ private boolean isRelevantHelper() {
+ return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
+ }
+
+ @Override
+ public void event(KubevirtLoadBalancerEvent event) {
+ switch (event.type()) {
+ case KUBEVIRT_LOAD_BALANCER_CREATED:
+ eventExecutor.execute(() -> processLbCreated(event.subject()));
+ break;
+ case KUBEVIRT_LOAD_BALANCER_UPDATED:
+ eventExecutor.execute(() -> processLbUpdated(event.subject(), event.oldLb()));
+ break;
+ case KUBEVIRT_LOAD_BALANCER_REMOVED:
+ eventExecutor.execute(() -> processLbRemoved(event.subject()));
+ break;
+ default:
+ //do nothing
+ break;
+ }
+ }
+
+ private void processLbCreated(KubevirtLoadBalancer loadBalancer) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+
+ KubevirtNetwork network = networkService.network(loadBalancer.networkId());
+
+ if (network == null) {
+ log.warn("Failed to process processLbCreated because there's no network for lb {}",
+ loadBalancer.name());
+ return;
+ }
+
+ KubevirtRouter router =
+ getRouterForKubevirtNetwork(routerService, network);
+
+ if (router == null) {
+ log.warn("Failed to process processLbCreated because there's no router for lb {}",
+ loadBalancer.name());
+ return;
+ }
+
+ if (router.electedGateway() == null) {
+ log.warn("Failed to process processLbCreated because there's elected gateway for lb {}",
+ loadBalancer.name());
+ return;
+ }
+
+ KubevirtNode gateway = nodeService.node(router.electedGateway());
+
+ setLbGroup(loadBalancer, gateway, true);
+ setBucketsToGroup(loadBalancer, gateway, true);
+ setLbDownstreamRules(loadBalancer, router, gateway, true);
+ setLbUpstreamRules(loadBalancer, router, gateway, true);
+
+ if (network.type() == VXLAN || network.type() == GENEVE || network.type() == GRE) {
+ setLbDownStreamRulesForTunBridge(loadBalancer, gateway, true);
+ }
+ }
+
+ private void processLbUpdated(KubevirtLoadBalancer loadBalancer, KubevirtLoadBalancer old) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+ // clean up buckets and flow rules related to the old loadbalancer
+
+ KubevirtNetwork oldNetwork = networkService.network(loadBalancer.networkId());
+
+ if (oldNetwork == null) {
+ log.warn("Failed to process processLbUpdated because there's no network for lb {}",
+ loadBalancer.name());
+ return;
+ }
+
+ KubevirtRouter oldRouter =
+ getRouterForKubevirtNetwork(routerService, oldNetwork);
+
+ if (oldRouter == null) {
+ log.warn("Failed to process processLbUpdated because there's no router for lb {}",
+ loadBalancer.name());
+ return;
+ }
+
+ if (oldRouter.electedGateway() == null) {
+ log.warn("Failed to process processLbUpdated because there's elected gateway for lb {}",
+ loadBalancer.name());
+ return;
+ }
+ KubevirtNode oldGateway = nodeService.node(oldRouter.electedGateway());
+
+ setLbDownstreamRules(old, oldRouter, oldGateway, false);
+ setLbUpstreamRules(old, oldRouter, oldGateway, false);
+ if (oldNetwork.type() == VXLAN || oldNetwork.type() == GENEVE || oldNetwork.type() == GRE) {
+ setLbDownStreamRulesForTunBridge(loadBalancer, oldGateway, false);
+ }
+ setBucketsToGroup(old, oldGateway, false);
+ setLbGroup(old, oldGateway, false);
+
+
+ KubevirtNetwork network = networkService.network(loadBalancer.networkId());
+
+ if (network == null) {
+ log.warn("Failed to process processLbUpdated because there's no network for lb {}",
+ loadBalancer.name());
+ return;
+ }
+
+ KubevirtRouter router =
+ getRouterForKubevirtNetwork(routerService, network);
+
+ if (router == null) {
+ log.warn("Failed to process processLbUpdated because there's no router for lb {}",
+ loadBalancer.name());
+ return;
+ }
+
+ if (router.electedGateway() == null) {
+ log.warn("Failed to process processLbUpdated because there's elected gateway for lb {}",
+ loadBalancer.name());
+ return;
+ }
+
+ KubevirtNode gateway = nodeService.node(router.electedGateway());
+
+ setLbGroup(loadBalancer, gateway, true);
+ setBucketsToGroup(loadBalancer, gateway, true);
+ setLbDownstreamRules(loadBalancer, router, gateway, true);
+ setLbUpstreamRules(loadBalancer, router, gateway, true);
+ if (network.type() == VXLAN || network.type() == GENEVE || network.type() == GRE) {
+ setLbDownStreamRulesForTunBridge(loadBalancer, gateway, true);
+ }
+ }
+
+ private void processLbRemoved(KubevirtLoadBalancer loadBalancer) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+
+ KubevirtNetwork network = networkService.network(loadBalancer.networkId());
+
+ if (network == null) {
+ log.warn("Failed to process processLbRemoved because there's no network for lb {}",
+ loadBalancer.name());
+ return;
+ }
+
+ KubevirtRouter router =
+ getRouterForKubevirtNetwork(routerService, network);
+
+ if (router == null) {
+ log.warn("Failed to process processLbRemoved because there's no router for lb {}",
+ loadBalancer.name());
+ return;
+ }
+
+ if (router.electedGateway() == null) {
+ log.warn("Failed to process processLbRemoved because there's elected gateway for lb {}",
+ loadBalancer.name());
+ return;
+ }
+
+ KubevirtNode gateway = nodeService.node(router.electedGateway());
+
+ setLbDownstreamRules(loadBalancer, router, gateway, false);
+ setLbUpstreamRules(loadBalancer, router, gateway, false);
+ setBucketsToGroup(loadBalancer, gateway, false);
+ setLbGroup(loadBalancer, gateway, false);
+
+ if (network.type() == VXLAN || network.type() == GENEVE || network.type() == GRE) {
+ setLbDownStreamRulesForTunBridge(loadBalancer, gateway, false);
+ }
+ }
+ }
+
+ private void setLbGroup(KubevirtLoadBalancer loadBalancer, KubevirtNode gateway, boolean install) {
+
+ int groupId = loadBalancer.hashCode();
+
+ groupRuleService.setRule(appId, gateway.intgBridge(), groupId,
+ SELECT, Lists.newArrayList(), install);
+ }
+
+ private void setBucketsToGroup(KubevirtLoadBalancer loadBalancer, KubevirtNode gateway, boolean install) {
+ int groupId = loadBalancer.hashCode();
+
+ KubevirtNetwork network = networkService.network(loadBalancer.networkId());
+
+ Set<KubevirtPort> ports = portService.ports(loadBalancer.networkId());
+
+ List<GroupBucket> bkts = Lists.newArrayList();
+ loadBalancer.members().forEach(ip -> {
+ ports.stream().filter(port -> port.ipAddress().equals(ip) && port.macAddress() != null)
+ .findAny().ifPresent(port -> bkts.add(buildGroupBucket(port)));
+ });
+
+ groupRuleService.setBuckets(appId, gateway.intgBridge(),
+ groupId, bkts, install);
+ }
+
+ private void setLbDownstreamRules(KubevirtLoadBalancer loadBalancer,
+ KubevirtRouter router,
+ KubevirtNode gateway, boolean install) {
+
+ int groupId = loadBalancer.hashCode();
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setEthSrc(router.mac())
+ .group(GroupId.valueOf(groupId))
+ .build();
+
+ loadBalancer.rules().forEach(rule -> {
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
+ switch (rule.protocol().toUpperCase()) {
+ case PROTOCOL_TCP:
+ sBuilder.matchIPDst(loadBalancer.vip().toIpPrefix())
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_TCP)
+ .matchTcpDst(TpPort.tpPort(rule.portRangeMin().intValue()));
+ break;
+ case PROTOCOL_UDP:
+ sBuilder.matchIPDst(loadBalancer.vip().toIpPrefix())
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_UDP)
+ .matchUdpDst(TpPort.tpPort(rule.portRangeMin().intValue()));
+ break;
+ case PROTOCOL_ICMP:
+ sBuilder.matchIPDst(loadBalancer.vip().toIpPrefix())
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPProtocol(IPv4.PROTOCOL_ICMP);
+ break;
+ default:
+ break;
+ }
+
+ flowRuleService.setRule(
+ appId,
+ gateway.intgBridge(),
+ sBuilder.build(),
+ treatment,
+ PRIORITY_LB_RULE,
+ GW_DROP_TABLE,
+ install
+ );
+ });
+ }
+
+ private void setLbDownstreamRulesForFloatingIp(KubevirtNode gateway,
+ KubevirtFloatingIp floatingIp,
+ boolean install) {
+
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPDst(floatingIp.floatingIp().toIpPrefix());
+
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
+ .setIpDst(floatingIp.fixedIp())
+ .transition(GW_DROP_TABLE);
+
+ flowRuleService.setRule(
+ appId,
+ gateway.intgBridge(),
+ sBuilder.build(),
+ tBuilder.build(),
+ PRIORITY_LB_RULE,
+ GW_ENTRY_TABLE,
+ install);
+ }
+
+ private void setLbDownStreamRulesForTunBridge(KubevirtLoadBalancer loadBalancer,
+ KubevirtNode gateway, boolean install) {
+ Set<KubevirtPort> ports = portService.ports(loadBalancer.networkId());
+ KubevirtNetwork network = networkService.network(loadBalancer.networkId());
+
+ PortNumber tunnelPortNumber = tunnelPort(gateway, network);
+ if (tunnelPortNumber == null) {
+ return;
+ }
+
+ loadBalancer.members().forEach(ip -> {
+ ports.stream().filter(port -> port.ipAddress().equals(ip) && port.macAddress() != null)
+ .findAny().ifPresent(port -> {
+
+ KubevirtNode workerNode = nodeService.node(port.deviceId());
+
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchIPDst(IpPrefix.valueOf(port.ipAddress(), 32))
+ .matchEthDst(port.macAddress());
+
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
+ .setTunnelId(Long.parseLong(network.segmentId()))
+ .extension(buildExtension(
+ deviceService,
+ gateway.tunBridge(),
+ workerNode.dataIp().getIp4Address()),
+ gateway.tunBridge())
+ .setOutput(tunnelPortNumber);
+
+ flowRuleService.setRule(
+ appId,
+ gateway.tunBridge(),
+ sBuilder.build(),
+ tBuilder.build(),
+ PRIORITY_LB_GATEWAY_TUN_BRIDGE_RULE,
+ TUNNEL_DEFAULT_TABLE,
+ install);
+ });
+ });
+ }
+ private void setLbUpstreamRules(KubevirtLoadBalancer loadBalancer,
+ KubevirtRouter router,
+ KubevirtNode gateway, boolean install) {
+
+ Set<KubevirtPort> ports = portService.ports(loadBalancer.networkId());
+
+ loadBalancer.members().forEach(ip -> {
+ ports.stream().filter(port -> port.ipAddress().equals(ip) && port.macAddress() != null)
+ .findAny().ifPresent(port -> {
+ loadBalancer.rules().forEach(rule -> {
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchEthSrc(port.macAddress())
+ .matchIPSrc(port.ipAddress().toIpPrefix());
+
+ switch (rule.protocol().toUpperCase()) {
+ case PROTOCOL_TCP:
+ sBuilder.matchIPProtocol(IPv4.PROTOCOL_TCP)
+ .matchTcpSrc(TpPort.tpPort(rule.portRangeMin()));
+ break;
+ case PROTOCOL_UDP:
+ sBuilder.matchIPProtocol(IPv4.PROTOCOL_UDP)
+ .matchUdpSrc(TpPort.tpPort(rule.portRangeMin()));
+ break;
+ case PROTOCOL_ICMP:
+ sBuilder.matchIPProtocol(IPv4.PROTOCOL_ICMP);
+ break;
+ default:
+ break;
+ }
+
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
+ .setEthSrc(router.mac())
+ .setIpSrc(loadBalancer.vip())
+ .transition(GW_DROP_TABLE);
+
+ flowRuleService.setRule(
+ appId,
+ gateway.intgBridge(),
+ sBuilder.build(),
+ tBuilder.build(),
+ PRIORITY_LB_RULE,
+ GW_ENTRY_TABLE,
+ install);
+ });
+ });
+ });
+ }
+
+ private void setArpResponseRuleForFloatingIp(KubevirtNode gateway,
+ KubevirtFloatingIp floatingIp,
+ boolean install) {
+ TrafficSelector selector = DefaultTrafficSelector.builder()
+ .matchInPort(externalPatchPortNum(deviceService, gateway))
+ .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+ .matchArpOp(ARP.OP_REQUEST)
+ .matchArpTpa(floatingIp.floatingIp().getIp4Address())
+ .build();
+
+ Device device = deviceService.getDevice(gateway.intgBridge());
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .extension(RulePopulatorUtil.buildMoveEthSrcToDstExtension(device), device.id())
+ .extension(RulePopulatorUtil.buildMoveArpShaToThaExtension(device), device.id())
+ .extension(RulePopulatorUtil.buildMoveArpSpaToTpaExtension(device), device.id())
+ .setArpOp(ARP.OP_REPLY)
+ .setEthSrc(DEFAULT_GATEWAY_MAC)
+ .setArpSha(DEFAULT_GATEWAY_MAC)
+ .setArpSpa(floatingIp.floatingIp().getIp4Address())
+ .setOutput(PortNumber.IN_PORT)
+ .build();
+
+ flowRuleService.setRule(
+ appId,
+ gateway.intgBridge(),
+ selector,
+ treatment,
+ PRIORITY_ARP_GATEWAY_RULE,
+ GW_ENTRY_TABLE,
+ install);
+ }
+ private void setLbUpstreamRulesForFloatingIp(KubevirtRouter router,
+ KubevirtNode gateway,
+ KubevirtFloatingIp floatingIp,
+ boolean install) {
+ if (router.peerRouter().macAddress() == null) {
+ return;
+ }
+
+ TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
+ .matchEthType(Ethernet.TYPE_IPV4)
+ .matchEthSrc(router.mac())
+ .matchIPSrc(floatingIp.fixedIp().toIpPrefix());
+
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
+ .setEthSrc(DEFAULT_GATEWAY_MAC)
+ .setIpSrc(floatingIp.floatingIp())
+ .setEthDst(router.peerRouter().macAddress())
+ .setOutput(externalPatchPortNum(deviceService, gateway));
+
+ flowRuleService.setRule(
+ appId,
+ gateway.intgBridge(),
+ sBuilder.build(),
+ tBuilder.build(),
+ PRIORITY_LB_RULE,
+ GW_DROP_TABLE,
+ install);
+ }
+
+ private GroupBucket buildGroupBucket(KubevirtPort port) {
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+ tBuilder.setEthDst(port.macAddress())
+ .setIpDst(port.ipAddress())
+ .setOutput(PortNumber.NORMAL);
+
+ return DefaultGroupBucket.createSelectGroupBucket(tBuilder.build());
+ }
+
+ private class InternalRouterEventListener implements KubevirtRouterListener {
+ private boolean isRelevantHelper() {
+ return Objects.equals(localNodeId, leadershipService.getLeader(appId.name()));
+ }
+
+ @Override
+ public void event(KubevirtRouterEvent event) {
+ switch (event.type()) {
+ case KUBEVIRT_GATEWAY_NODE_ATTACHED:
+ eventExecutor.execute(() -> processRouterGatewayNodeAttached(event.subject(),
+ event.gateway()));
+ break;
+ case KUBEVIRT_GATEWAY_NODE_CHANGED:
+ eventExecutor.execute(() -> processRouterGatewayNodeChanged(event.subject(),
+ event.gateway()));
+ break;
+ case KUBEVIRT_GATEWAY_NODE_DETACHED:
+ eventExecutor.execute(() -> processRouterGatewayNodeDetached(event.subject(),
+ event.gateway()));
+ break;
+
+ case KUBEVIRT_FLOATING_IP_LB_ASSOCIATED:
+ eventExecutor.execute(() -> processFloatingIpAssociated(event.subject(),
+ event.floatingIp()));
+ break;
+ case KUBEVIRT_FLOATING_IP_LB_DISASSOCIATED:
+ eventExecutor.execute(() -> processFloatingIpDisAssociated(event.subject(),
+ event.floatingIp()));
+ break;
+ case KUBEVIRT_PEER_ROUTER_MAC_RETRIEVED:
+ eventExecutor.execute(() -> processPeerRouterRetrieved(event.subject()));
+ break;
+ default:
+ //do nothing
+ break;
+ }
+ }
+
+ private void processPeerRouterRetrieved(KubevirtRouter router) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+
+ if (router.peerRouter().macAddress() == null) {
+ return;
+ }
+
+ if (router.electedGateway() == null) {
+ return;
+ }
+
+ processRouterGatewayNodeAttached(router, router.electedGateway());
+ }
+
+ private void processFloatingIpAssociated(KubevirtRouter router, KubevirtFloatingIp floatingIp) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+
+ if (router.electedGateway() == null) {
+ log.warn("Failed to process processFloatingIpAssociated because there's elected gateway for fip {}",
+ floatingIp.floatingIp());
+ return;
+ }
+
+ KubevirtNode gateway = nodeService.node(router.electedGateway());
+
+ loadBalancerService.loadBalancers().stream()
+ .filter(lb -> lb.vip().equals(floatingIp.fixedIp()))
+ .findAny()
+ .ifPresent(lb -> {
+ setLbUpstreamRulesForFloatingIp(router, gateway, floatingIp, true);
+ setLbDownstreamRulesForFloatingIp(gateway, floatingIp, true);
+ setArpResponseRuleForFloatingIp(gateway, floatingIp, true);
+ processGarpPacketForFloatingIp(floatingIp, gateway);
+ });
+ }
+
+ private void processGarpPacketForFloatingIp(KubevirtFloatingIp floatingIp, KubevirtNode electedGw) {
+ if (floatingIp == null) {
+ return;
+ }
+
+ Ethernet ethernet = buildGarpPacket(DEFAULT_GATEWAY_MAC, floatingIp.floatingIp());
+ if (ethernet == null) {
+ return;
+ }
+
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+ .setOutput(externalPatchPortNum(deviceService, electedGw)).build();
+
+ packetService.emit(new DefaultOutboundPacket(electedGw.intgBridge(), treatment,
+ ByteBuffer.wrap(ethernet.serialize())));
+ }
+
+ private void processFloatingIpDisAssociated(KubevirtRouter router, KubevirtFloatingIp floatingIp) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+
+ if (router.electedGateway() == null) {
+ log.warn("Failed to process processFloatingIpDisAssociated because there's elected gateway for fip {}",
+ floatingIp.floatingIp());
+ return;
+ }
+
+ KubevirtNode gateway = nodeService.node(router.electedGateway());
+
+
+ loadBalancerService.loadBalancers().stream()
+ .filter(lb -> lb.vip().equals(floatingIp.fixedIp()))
+ .findAny()
+ .ifPresent(lb -> {
+ setLbUpstreamRulesForFloatingIp(router, gateway, floatingIp, false);
+ setLbDownstreamRulesForFloatingIp(gateway, floatingIp, false);
+ setArpResponseRuleForFloatingIp(gateway, floatingIp, false);
+ });
+ }
+
+ private void processRouterGatewayNodeAttached(KubevirtRouter router,
+ String associatedGateway) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+
+ KubevirtNode gatewayNode = nodeService.node(associatedGateway);
+ if (gatewayNode == null) {
+ return;
+ }
+
+ getLoadBalancerSetForRouter(router, loadBalancerService).forEach(loadBalancer -> {
+ setLbGroup(loadBalancer, gatewayNode, true);
+ setBucketsToGroup(loadBalancer, gatewayNode, true);
+ setLbDownstreamRules(loadBalancer, router, gatewayNode, true);
+ setLbUpstreamRules(loadBalancer, router, gatewayNode, true);
+
+ KubevirtNetwork network = networkService.network(loadBalancer.networkId());
+ if (network.type() == VXLAN || network.type() == GENEVE || network.type() == GRE) {
+ setLbDownStreamRulesForTunBridge(loadBalancer, gatewayNode, true);
+ }
+
+ routerService.floatingIpsByRouter(router.name())
+ .stream()
+ .filter(fip -> fip.fixedIp() != null && fip.fixedIp().equals(loadBalancer.vip()))
+ .findAny()
+ .ifPresent(fip -> {
+ setLbDownstreamRulesForFloatingIp(gatewayNode, fip, true);
+ setLbUpstreamRulesForFloatingIp(router, gatewayNode, fip, true);
+ setArpResponseRuleForFloatingIp(gatewayNode, fip, true);
+ });
+ });
+ }
+
+ private void processRouterGatewayNodeDetached(KubevirtRouter router,
+ String disAssociatedGateway) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+
+ KubevirtNode gatewayNode = nodeService.node(disAssociatedGateway);
+ if (gatewayNode == null) {
+ return;
+ }
+
+ getLoadBalancerSetForRouter(router, loadBalancerService).forEach(loadBalancer -> {
+ setLbDownstreamRules(loadBalancer, router, gatewayNode, false);
+ setLbUpstreamRules(loadBalancer, router, gatewayNode, false);
+ setBucketsToGroup(loadBalancer, gatewayNode, false);
+ setLbGroup(loadBalancer, gatewayNode, false);
+
+ KubevirtNetwork network = networkService.network(loadBalancer.networkId());
+ if (network.type() == VXLAN || network.type() == GENEVE || network.type() == GRE) {
+ setLbDownStreamRulesForTunBridge(loadBalancer, gatewayNode, false);
+ }
+
+ routerService.floatingIpsByRouter(router.name())
+ .stream()
+ .filter(fip -> fip.fixedIp() != null && fip.fixedIp().equals(loadBalancer.vip()))
+ .findAny()
+ .ifPresent(fip -> {
+ setLbDownstreamRulesForFloatingIp(gatewayNode, fip, false);
+ setLbUpstreamRulesForFloatingIp(router, gatewayNode, fip, false);
+ setArpResponseRuleForFloatingIp(gatewayNode, fip, false);
+ });
+ });
+ }
+
+ private void processRouterGatewayNodeChanged(KubevirtRouter router,
+ String disAssociatedGateway) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+
+ processRouterGatewayNodeDetached(router, disAssociatedGateway);
+
+ KubevirtNode newGatewayNode = nodeService.node(router.electedGateway());
+ if (newGatewayNode == null) {
+ return;
+ }
+ processRouterGatewayNodeAttached(router, newGatewayNode.hostname());
+ }
+ }
+}
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 c3ba661..466ae9a 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
@@ -1088,8 +1088,6 @@
if (!isRelevantHelper()) {
return;
}
- log.info("###### processRouterGatewayNodeAttached called for router {} and new router is {}",
- router.name(), associatedGateway);
KubevirtNode gatewayNode = nodeService.node(associatedGateway);
if (gatewayNode == null) {
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingArpHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingArpHandler.java
index 40f492d..a1c1415 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingArpHandler.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingArpHandler.java
@@ -244,12 +244,24 @@
case KUBEVIRT_GATEWAY_NODE_DETACHED:
eventExecutor.execute(() -> processRouterGatewayNodeDetached(event.subject(), event.gateway()));
break;
+ case KUBEVIRT_GATEWAY_NODE_CHANGED:
+ eventExecutor.execute(() -> processRouterGatewayNodeChanged(event.subject(),
+ event.gateway()));
+ break;
default:
//do nothing
break;
}
}
+ private void processRouterGatewayNodeChanged(KubevirtRouter router, String oldGateway) {
+ if (!isRelevantHelper()) {
+ return;
+ }
+ processRouterGatewayNodeDetached(router, oldGateway);
+ processRouterExternalNetAttachedOrGwAttached(router);
+ }
+
private void processRouterExternalNetAttachedOrGwAttached(KubevirtRouter router) {
if (!isRelevantHelper()) {
return;
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingSnatHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingSnatHandler.java
index 6e46179..e73bd01 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingSnatHandler.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtRoutingSnatHandler.java
@@ -173,7 +173,7 @@
}
private void initGatewayNodeSnatForRouter(KubevirtRouter router, String gateway, boolean install) {
- if (router.electedGateway() == null) {
+ if (gateway == null) {
log.warn("Fail to initialize gateway node snat for router {} " +
"because there's no gateway assigned to it", router.name());
return;
@@ -509,7 +509,7 @@
if (!isRelevantHelper()) {
return;
}
- KubevirtNode electedGw = gatewayNodeForSpecifiedRouter(kubevirtNodeService, router);
+ KubevirtNode electedGw = kubevirtNodeService.node(router.electedGateway());
if (electedGw == null) {
log.warn("Fail to process router external network attached gateway node snat for router {} " +
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/util/KubevirtNetworkingUtil.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/util/KubevirtNetworkingUtil.java
index bfb2916..8771dda 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/util/KubevirtNetworkingUtil.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/util/KubevirtNetworkingUtil.java
@@ -35,6 +35,8 @@
import org.onlab.packet.MacAddress;
import org.onosproject.cfg.ConfigProperty;
import org.onosproject.kubevirtnetworking.api.DefaultKubevirtPort;
+import org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancer;
+import org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancerService;
import org.onosproject.kubevirtnetworking.api.KubevirtNetwork;
import org.onosproject.kubevirtnetworking.api.KubevirtNetworkService;
import org.onosproject.kubevirtnetworking.api.KubevirtPort;
@@ -48,6 +50,8 @@
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.GroupKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xbill.DNS.Address;
@@ -634,4 +638,29 @@
return ethernet;
}
+
+ /**
+ * Obtains flow group key from the given id.
+ *
+ * @param groupId flow group identifier
+ * @return flow group key
+ */
+ public static GroupKey getGroupKey(int groupId) {
+ return new DefaultGroupKey((Integer.toString(groupId)).getBytes());
+ }
+
+ /**
+ * Obtains load balancer set from the given router.
+ *
+ * @param router kubevirt router
+ * @param lbService kubevirt loadbalancer service
+ * @return loadbalancer set
+ */
+ public static Set<KubevirtLoadBalancer> getLoadBalancerSetForRouter(KubevirtRouter router,
+ KubevirtLoadBalancerService lbService) {
+
+ return lbService.loadBalancers().stream()
+ .filter(lb -> router.internal().contains(lb.networkId()))
+ .collect(Collectors.toSet());
+ }
}
diff --git a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtLoadBalancerCodecTest.java b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtLoadBalancerCodecTest.java
index 7aed6f8..cd86402 100644
--- a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtLoadBalancerCodecTest.java
+++ b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtLoadBalancerCodecTest.java
@@ -68,6 +68,10 @@
.portRangeMin(8000)
.build();
+ private static final KubevirtLoadBalancerRule RULE3 = DefaultKubevirtLoadBalancerRule.builder()
+ .protocol("icmp")
+ .build();
+
final CoreService mockCoreService = createMock(CoreService.class);
private static final String REST_APP_ID = "org.onosproject.rest";
@@ -97,7 +101,7 @@
.vip(IpAddress.valueOf("10.10.10.10"))
.members(ImmutableSet.of(IpAddress.valueOf("10.10.10.11"),
IpAddress.valueOf("10.10.10.12")))
- .rules(ImmutableSet.of(RULE1, RULE2))
+ .rules(ImmutableSet.of(RULE1, RULE2, RULE3))
.description("network load balancer")
.build();
@@ -123,7 +127,7 @@
assertThat(true, is(expectedMembers.containsAll(realMembers)));
assertThat(true, is(realMembers.containsAll(expectedMembers)));
- Set<KubevirtLoadBalancerRule> expectedRules = ImmutableSet.of(RULE1, RULE2);
+ Set<KubevirtLoadBalancerRule> expectedRules = ImmutableSet.of(RULE1, RULE2, RULE3);
Set<KubevirtLoadBalancerRule> realRules = lb.rules();
assertThat(true, is(expectedRules.containsAll(realRules)));
assertThat(true, is(realRules.containsAll(expectedRules)));
diff --git a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/impl/KubevirtRouterManagerTest.java b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/impl/KubevirtRouterManagerTest.java
index 94b3161..26d7088 100644
--- a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/impl/KubevirtRouterManagerTest.java
+++ b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/impl/KubevirtRouterManagerTest.java
@@ -18,6 +18,7 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import com.google.common.util.concurrent.MoreExecutors;
import org.junit.After;
import org.junit.Before;
@@ -32,6 +33,9 @@
import org.onosproject.kubevirtnetworking.api.DefaultKubevirtFloatingIp;
import org.onosproject.kubevirtnetworking.api.DefaultKubevirtRouter;
import org.onosproject.kubevirtnetworking.api.KubevirtFloatingIp;
+import org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancer;
+import org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancerListener;
+import org.onosproject.kubevirtnetworking.api.KubevirtLoadBalancerService;
import org.onosproject.kubevirtnetworking.api.KubevirtPeerRouter;
import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
import org.onosproject.kubevirtnetworking.api.KubevirtRouterEvent;
@@ -140,9 +144,11 @@
@Before
public void setUp() throws Exception {
kubevirtRouterStore = new DistributedKubevirtRouterStore();
+
TestUtils.setField(kubevirtRouterStore, "coreService", new TestCoreService());
TestUtils.setField(kubevirtRouterStore, "storageService", new TestStorageService());
TestUtils.setField(kubevirtRouterStore, "eventExecutor", MoreExecutors.newDirectExecutorService());
+ TestUtils.setField(kubevirtRouterStore, "loadBalancerService", new TestLoadBalancerService());
kubevirtRouterStore.activate();
target = new KubevirtRouterManager();
@@ -499,4 +505,27 @@
assertEquals("internal addition entries", internal, testListener.internalRemoved);
testListener.internalRemoved.clear();
}
+
+ private class TestLoadBalancerService implements KubevirtLoadBalancerService {
+
+ @Override
+ public KubevirtLoadBalancer loadBalancer(String name) {
+ return null;
+ }
+
+ @Override
+ public Set<KubevirtLoadBalancer> loadBalancers() {
+ return Sets.newHashSet();
+ }
+
+ @Override
+ public void addListener(KubevirtLoadBalancerListener listener) {
+
+ }
+
+ @Override
+ public void removeListener(KubevirtLoadBalancerListener listener) {
+
+ }
+ }
}
diff --git a/apps/kubevirt-networking/app/src/test/resources/org/onosproject/kubevirtnetworking/codec/KubevirtLoadBalancer.json b/apps/kubevirt-networking/app/src/test/resources/org/onosproject/kubevirtnetworking/codec/KubevirtLoadBalancer.json
index daf43e2..806fd73 100644
--- a/apps/kubevirt-networking/app/src/test/resources/org/onosproject/kubevirtnetworking/codec/KubevirtLoadBalancer.json
+++ b/apps/kubevirt-networking/app/src/test/resources/org/onosproject/kubevirtnetworking/codec/KubevirtLoadBalancer.json
@@ -17,6 +17,9 @@
"protocol": "udp",
"portRangeMax": 9000,
"portRangeMin": 8000
+ },
+ {
+ "protocol" : "icmp"
}
]
}
\ No newline at end of file