Initial implementation of SNAT functionality.
Change-Id: I9094755c6d25a62e527976b9bf275d7c1e2a3f86
(cherry picked from commit b9a220261df1f591b75d59b646aa834c1efdb7f1)
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 d852ca4..f40d42c 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
@@ -27,15 +27,19 @@
import org.json.JSONException;
import org.json.JSONObject;
import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onosproject.cfg.ConfigProperty;
import org.onosproject.kubevirtnetworking.api.DefaultKubevirtPort;
import org.onosproject.kubevirtnetworking.api.KubevirtNetwork;
import org.onosproject.kubevirtnetworking.api.KubevirtPort;
+import org.onosproject.kubevirtnetworking.api.KubevirtRouter;
+import org.onosproject.kubevirtnetworking.api.KubevirtRouterService;
import org.onosproject.kubevirtnode.api.KubevirtApiConfig;
import org.onosproject.kubevirtnode.api.KubevirtApiConfigService;
import org.onosproject.kubevirtnode.api.KubevirtNode;
+import org.onosproject.kubevirtnode.api.KubevirtNodeService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
@@ -54,6 +58,7 @@
import java.util.stream.Collectors;
import static org.onosproject.kubevirtnetworking.api.Constants.TUNNEL_TO_TENANT_PREFIX;
+import static org.onosproject.kubevirtnode.api.KubevirtNode.Type.GATEWAY;
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
/**
@@ -83,8 +88,8 @@
/**
* Obtains the boolean property value with specified property key name.
*
- * @param properties a collection of properties
- * @param name key name
+ * @param properties a collection of properties
+ * @param name key name
* @return mapping value
*/
public static boolean getPropertyValueAsBoolean(Set<ConfigProperty> properties,
@@ -99,7 +104,7 @@
* Re-structures the OVS port name.
* The length of OVS port name should be not large than 15.
*
- * @param portName original port name
+ * @param portName original port name
* @return re-structured OVS port name
*/
public static String structurePortName(String portName) {
@@ -146,8 +151,8 @@
/**
* Prints out the JSON string in pretty format.
*
- * @param mapper Object mapper
- * @param jsonString JSON string
+ * @param mapper Object mapper
+ * @param jsonString JSON string
* @return pretty formatted JSON string
*/
public static String prettyJson(ObjectMapper mapper, String jsonString) {
@@ -185,8 +190,8 @@
/**
* Calculate the broadcast address from given IP address and subnet prefix length.
*
- * @param ipAddr IP address
- * @param prefixLength subnet prefix length
+ * @param ipAddr IP address
+ * @param prefixLength subnet prefix length
* @return broadcast address
*/
public static String getBroadcastAddr(String ipAddr, int prefixLength) {
@@ -194,12 +199,13 @@
SubnetUtils utils = new SubnetUtils(subnet);
return utils.getInfo().getBroadcastAddress();
}
+
/**
* Generates endpoint URL by referring to scheme, ipAddress and port.
*
- * @param scheme scheme
- * @param ipAddress IP address
- * @param port port number
+ * @param scheme scheme
+ * @param ipAddress IP address
+ * @param port port number
* @return generated endpoint URL
*/
public static String endpoint(KubevirtApiConfig.Scheme scheme, IpAddress ipAddress, int port) {
@@ -218,7 +224,7 @@
/**
* Generates endpoint URL by referring to scheme, ipAddress and port.
*
- * @param apiConfig kubernetes API config
+ * @param apiConfig kubernetes API config
* @return generated endpoint URL
*/
public static String endpoint(KubevirtApiConfig apiConfig) {
@@ -289,7 +295,7 @@
* Obtains the tunnel port number with the given network and node.
*
* @param network kubevirt network
- * @param node kubevirt node
+ * @param node kubevirt node
* @return tunnel port number
*/
public static PortNumber tunnelPort(KubevirtNetwork network, KubevirtNode node) {
@@ -310,7 +316,7 @@
* Obtains the kubevirt port from kubevirt POD.
*
* @param networks set of existing kubevirt networks
- * @param pod kubevirt POD
+ * @param pod kubevirt POD
* @return kubevirt port
*/
public static KubevirtPort getPort(Set<KubevirtNetwork> networks, Pod pod) {
@@ -365,7 +371,7 @@
/**
* Obtains the tunnel bridge to tenant bridge patch port number.
*
- * @param node kubevirt node
+ * @param node kubevirt node
* @param network kubevirt network
* @return patch port number
*/
@@ -385,7 +391,7 @@
/**
* Obtains the tunnel port number of the given node.
*
- * @param node kubevirt node
+ * @param node kubevirt node
* @param network kubevirt network
* @return tunnel port number
*/
@@ -432,4 +438,64 @@
return port != null ? port.number() : null;
}
+ /**
+ * Returns the gateway node for the specified kubevirt router.
+ * Among gateways, only one gateway would act as a gateway per perter.
+ * Currently gateway node is selected based on modulo operation with router hashcode.
+ *
+ * @param nodeService kubevirt node service
+ * @param router kubevirt router
+ * @return elected gateway node
+ */
+ public static KubevirtNode gatewayNodeForSpecifiedRouter(KubevirtNodeService nodeService,
+ KubevirtRouter router) {
+ //TODO: enhance election logic for a better load balancing
+
+ int numOfGateways = nodeService.completeNodes(GATEWAY).size();
+ if (numOfGateways == 0) {
+ return null;
+ }
+ return (KubevirtNode) nodeService.completeNodes(GATEWAY).toArray()[router.hashCode() % numOfGateways];
+ }
+
+ /**
+ * Returns the mac address of the br-int port of specified device.
+ *
+ * @param deviceService device service
+ * @param deviceId device Id
+ * @return mac address of the br-int port
+ */
+ public static MacAddress getbrIntMacAddress(DeviceService deviceService,
+ DeviceId deviceId) {
+ return MacAddress.valueOf(deviceService.getPorts(deviceId).stream()
+ .filter(port -> Objects.equals(port.annotations().value(PORT_NAME), "br-int"))
+ .map(port -> port.annotations().value("portMac"))
+ .findAny().orElse(null));
+ }
+
+ /**
+ * Returns the snat ip address with specified router.
+ *
+ * @param routerService router service
+ * @param internalNetworkId internal network id which is associated with the router
+ * @return snat ip address if exist, null otherwise
+ */
+ public static IpAddress getRouterSnatIpAddress(KubevirtRouterService routerService,
+ String internalNetworkId) {
+ KubevirtRouter router = routerService.routers().stream()
+ .filter(r -> r.internal().contains(internalNetworkId))
+ .findAny().orElse(null);
+
+ if (router == null) {
+ return null;
+ }
+
+ String routerSnatIp = router.external().keySet().stream().findAny().orElse(null);
+
+ if (routerSnatIp == null) {
+ return null;
+ }
+
+ return Ip4Address.valueOf(routerSnatIp);
+ }
}