diff options
Diffstat (limited to 'framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java')
-rw-r--r-- | framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java | 519 |
1 files changed, 0 insertions, 519 deletions
diff --git a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java b/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java deleted file mode 100644 index e03b25e8..00000000 --- a/framework/src/onos/apps/virtualbng/src/main/java/org/onosproject/virtualbng/VbngManager.java +++ /dev/null @@ -1,519 +0,0 @@ -/* - * Copyright 2015 Open Networking Laboratory - * - * 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.virtualbng; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.onlab.packet.Ethernet; -import org.onlab.packet.IpAddress; -import org.onlab.packet.IpPrefix; -import org.onlab.packet.MacAddress; -import org.onosproject.core.ApplicationId; -import org.onosproject.core.CoreService; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Host; -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.host.HostEvent; -import org.onosproject.net.host.HostListener; -import org.onosproject.net.host.HostService; -import org.onosproject.net.intent.IntentService; -import org.onosproject.net.intent.Key; -import org.onosproject.net.intent.PointToPointIntent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * This is a virtual Broadband Network Gateway (BNG) application. It mainly - * has 3 functions: - * (1) assigns and replies a public IP address to a REST request with a private - * IP address - * (2) maintains the mapping from the private IP address to the public IP address - * (3) installs point to point intents for the host configured with private IP - * address to access Internet - */ -@Component(immediate = true) -@Service -public class VbngManager implements VbngService { - - private static final String APP_NAME = "org.onosproject.virtualbng"; - private static final String VBNG_MAP_NAME = "vbng_mapping"; - - private final Logger log = LoggerFactory.getLogger(getClass()); - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected CoreService coreService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected HostService hostService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected IntentService intentService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected VbngConfigurationService vbngConfigurationService; - - private ApplicationId appId; - private Map<IpAddress, PointToPointIntent> p2pIntentsFromHost; - private Map<IpAddress, PointToPointIntent> p2pIntentsToHost; - - // This map stores the mapping from the private IP addresses to VcpeHost. - // The IP addresses in this map are all the private IP addresses we failed - // to create vBNGs due to the next hop host was not in ONOS. - private Map<IpAddress, VcpeHost> privateIpAddressMap; - - // Store the mapping from hostname to connect point - private Map<String, ConnectPoint> nodeToPort; - - private HostListener hostListener; - private IpAddress nextHopIpAddress; - - private static final DeviceId FABRIC_DEVICE_ID = - DeviceId.deviceId("of:8f0e486e73000187"); - - @Activate - public void activate() { - appId = coreService.registerApplication(APP_NAME); - p2pIntentsFromHost = new ConcurrentHashMap<>(); - p2pIntentsToHost = new ConcurrentHashMap<>(); - privateIpAddressMap = new ConcurrentHashMap<>(); - - nextHopIpAddress = vbngConfigurationService.getNextHopIpAddress(); - nodeToPort = vbngConfigurationService.getNodeToPort(); - hostListener = new InternalHostListener(); - hostService.addListener(hostListener); - - log.info("vBNG Started"); - - // Recover the status before vBNG restarts - statusRecovery(); - } - - @Deactivate - public void deactivate() { - hostService.removeListener(hostListener); - log.info("vBNG Stopped"); - } - - /** - * Recovers from XOS record. Re-sets up the mapping between private IP - * address and public IP address, re-calculates intents and re-installs - * those intents. - */ - private void statusRecovery() { - log.info("vBNG starts to recover from XOS record......"); - ObjectNode map; - try { - RestClient restClient = - new RestClient(vbngConfigurationService.getXosIpAddress(), - vbngConfigurationService.getXosRestPort()); - map = restClient.getRest(); - } catch (Exception e) { - log.error("Could not contact XOS", e); - return; - } - if (map == null) { - log.info("Stop to recover vBNG status due to the vBNG map " - + "is null!"); - return; - } - - log.info("Get record from XOS: {}", map); - - ArrayNode array = (ArrayNode) map.get(VBNG_MAP_NAME); - Iterator<JsonNode> entries = array.elements(); - while (entries.hasNext()) { - ObjectNode entry = (ObjectNode) entries.next(); - - IpAddress hostIpAdddress = - IpAddress.valueOf(entry.get("private_ip").asText()); - IpAddress publicIpAddress = - IpAddress.valueOf(entry.get("routeable_subnet").asText()); - MacAddress macAddress = - MacAddress.valueOf(entry.get("mac").asText()); - String hostName = entry.get("hostname").asText(); - - // Create vBNG - createVbng(hostIpAdddress, publicIpAddress, macAddress, hostName); - - } - } - - /** - * Creates a new vBNG. - * - * @param privateIpAddress a private IP address - * @param publicIpAddress the public IP address for the private IP address - * @param hostMacAddress the MAC address for the private IP address - * @param hostName the host name for the private IP address - */ - private void createVbng(IpAddress privateIpAddress, - IpAddress publicIpAddress, - MacAddress hostMacAddress, - String hostName) { - boolean result = vbngConfigurationService - .assignSpecifiedPublicIp(publicIpAddress, privateIpAddress); - if (!result) { - log.info("Assign public IP address {} for private IP address {} " - + "failed!", publicIpAddress, privateIpAddress); - log.info("Failed to create vBNG for private IP address {}", - privateIpAddress); - return; - } - log.info("[ADD] Private IP to Public IP mapping: {} --> {}", - privateIpAddress, publicIpAddress); - - // Setup paths between the host configured with private IP and - // next hop - if (!setupForwardingPaths(privateIpAddress, publicIpAddress, - hostMacAddress, hostName)) { - privateIpAddressMap.put(privateIpAddress, - new VcpeHost(hostMacAddress, hostName)); - } - } - - @Override - public IpAddress createVbng(IpAddress privateIpAddress, - MacAddress hostMacAddress, - String hostName) { - - IpAddress publicIpAddress = - vbngConfigurationService.getAvailablePublicIpAddress( - privateIpAddress); - if (publicIpAddress == null) { - log.info("Did not find an available public IP address to use."); - return null; - } - log.info("[ADD] Private IP to Public IP mapping: {} --> {}", - privateIpAddress, publicIpAddress); - - // Setup paths between the host configured with private IP and - // next hop - if (!setupForwardingPaths(privateIpAddress, publicIpAddress, - hostMacAddress, hostName)) { - privateIpAddressMap.put(privateIpAddress, - new VcpeHost(hostMacAddress, hostName)); - } - return publicIpAddress; - } - - @Override - public IpAddress deleteVbng(IpAddress privateIpAddress) { - // Recycle the public IP address assigned to this private IP address. - // Recycling will also delete the mapping entry from the private IP - // address to public IP address. - IpAddress assignedPublicIpAddress = vbngConfigurationService - .recycleAssignedPublicIpAddress(privateIpAddress); - if (assignedPublicIpAddress == null) { - return null; - } - - // Remove the private IP address from privateIpAddressMap - privateIpAddressMap.remove(privateIpAddress); - - // Remove intents - removeForwardingPaths(privateIpAddress); - - return assignedPublicIpAddress; - } - - /** - * Removes the forwarding paths in both two directions between host - * configured with private IP and next hop. - * - * @param privateIp the private IP address of a local host - */ - private void removeForwardingPaths(IpAddress privateIp) { - PointToPointIntent toNextHopIntent = - p2pIntentsFromHost.remove(privateIp); - if (toNextHopIntent != null) { - intentService.withdraw(toNextHopIntent); - //intentService.purge(toNextHopIntent); - } - PointToPointIntent toLocalHostIntent = - p2pIntentsToHost.remove(privateIp); - if (toLocalHostIntent != null) { - intentService.withdraw(toLocalHostIntent); - //intentService.purge(toLocalHostIntent); - } - } - - /** - * Sets up forwarding paths in both two directions between host configured - * with private IP and next hop. - * - * @param privateIp the private IP address of a local host - * @param publicIp the public IP address assigned for the private IP address - * @param hostMacAddress the MAC address for the IP address - * @param hostName the host name for the IP address - */ - private boolean setupForwardingPaths(IpAddress privateIp, - IpAddress publicIp, - MacAddress hostMacAddress, - String hostName) { - checkNotNull(privateIp); - checkNotNull(publicIp); - checkNotNull(hostMacAddress); - checkNotNull(hostName); - - if (nextHopIpAddress == null) { - log.warn("Did not find next hop IP address"); - return false; - } - - // If there are already intents for private IP address in the system, - // we will do nothing and directly return. - if (p2pIntentsFromHost.containsKey(privateIp) - && p2pIntentsToHost.containsKey(privateIp)) { - return true; - } - - Host nextHopHost = null; - if (!hostService.getHostsByIp(nextHopIpAddress).isEmpty()) { - nextHopHost = hostService.getHostsByIp(nextHopIpAddress) - .iterator().next(); - } else { - hostService.startMonitoringIp(nextHopIpAddress); - if (hostService.getHostsByIp(privateIp).isEmpty()) { - hostService.startMonitoringIp(privateIp); - } - return false; - } - - ConnectPoint nextHopConnectPoint = - new ConnectPoint(nextHopHost.location().elementId(), - nextHopHost.location().port()); - ConnectPoint localHostConnectPoint = nodeToPort.get(hostName); - - // Generate and install intent for traffic from host configured with - // private IP - if (!p2pIntentsFromHost.containsKey(privateIp)) { - PointToPointIntent toNextHopIntent - = srcMatchIntentGenerator(privateIp, - publicIp, - nextHopHost.mac(), - nextHopConnectPoint, - localHostConnectPoint - ); - p2pIntentsFromHost.put(privateIp, toNextHopIntent); - intentService.submit(toNextHopIntent); - } - - // Generate and install intent for traffic to host configured with - // private IP - if (!p2pIntentsToHost.containsKey(privateIp)) { - PointToPointIntent toLocalHostIntent - = dstMatchIntentGenerator(publicIp, - privateIp, - hostMacAddress, - localHostConnectPoint, - nextHopConnectPoint); - p2pIntentsToHost.put(privateIp, toLocalHostIntent); - intentService.submit(toLocalHostIntent); - } - - return true; - } - - /** - * Listener for host events. - */ - private class InternalHostListener implements HostListener { - @Override - public void event(HostEvent event) { - log.debug("Received HostEvent {}", event); - - Host host = event.subject(); - if (event.type() != HostEvent.Type.HOST_ADDED) { - return; - } - - for (IpAddress ipAddress: host.ipAddresses()) { - // The POST method from XOS gives us MAC and host name, so we - // do not need to do anything after receive a vCPE host event - // for now. - /*if (privateIpAddressSet.contains(ipAddress)) { - createVbngAgain(ipAddress); - }*/ - - if (nextHopIpAddress != null && - ipAddress.equals(nextHopIpAddress)) { - - for (Entry<IpAddress, VcpeHost> entry: - privateIpAddressMap.entrySet()) { - createVbngAgain(entry.getKey()); - } - - } - } - } - } - - /** - * Tries to create vBNG again after receiving a host event if the IP - * address of the host is the next hop IP address. - * - * @param privateIpAddress the private IP address - */ - private void createVbngAgain(IpAddress privateIpAddress) { - IpAddress publicIpAddress = vbngConfigurationService - .getAssignedPublicIpAddress(privateIpAddress); - if (publicIpAddress == null) { - // We only need to handle the private IP addresses for which we - // already returned the REST replies with assigned public IP - // addresses. If a private IP addresses does not have an assigned - // public IP address, we should not get it an available public IP - // address here, and we should delete it in the unhandled private - // IP address map. - privateIpAddressMap.remove(privateIpAddress); - return; - } - VcpeHost vcpeHost = privateIpAddressMap.get(privateIpAddress); - if (setupForwardingPaths(privateIpAddress, publicIpAddress, - vcpeHost.macAddress, vcpeHost.hostName)) { - privateIpAddressMap.remove(privateIpAddress); - } - } - - /** - * PointToPointIntent Generator. - * <p> - * The intent will match the source IP address in packet, rewrite the - * source IP address, and rewrite the destination MAC address. - * </p> - * - * @param srcIpAddress the source IP address in packet to match - * @param newSrcIpAddress the new source IP address to set - * @param dstMacAddress the destination MAC address to set - * @param dstConnectPoint the egress point - * @param srcConnectPoint the ingress point - * @return a PointToPointIntent - */ - private PointToPointIntent srcMatchIntentGenerator( - IpAddress srcIpAddress, - IpAddress newSrcIpAddress, - MacAddress dstMacAddress, - ConnectPoint dstConnectPoint, - ConnectPoint srcConnectPoint) { - checkNotNull(srcIpAddress); - checkNotNull(newSrcIpAddress); - checkNotNull(dstMacAddress); - checkNotNull(dstConnectPoint); - checkNotNull(srcConnectPoint); - - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); - selector.matchEthType(Ethernet.TYPE_IPV4); - selector.matchIPSrc(IpPrefix.valueOf(srcIpAddress, - IpPrefix.MAX_INET_MASK_LENGTH)); - - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); - treatment.setEthDst(dstMacAddress); - treatment.setIpSrc(newSrcIpAddress); - - Key key = Key.of(srcIpAddress.toString() + "MatchSrc", appId); - PointToPointIntent intent = PointToPointIntent.builder() - .appId(appId) - .key(key) - .selector(selector.build()) - .treatment(treatment.build()) - .egressPoint(dstConnectPoint) - .ingressPoint(srcConnectPoint) - .build(); - - log.info("Generated a PointToPointIntent for traffic from local host " - + ": {}", intent); - return intent; - } - - /** - * PointToPointIntent Generator. - * <p> - * The intent will match the destination IP address in packet, rewrite the - * destination IP address, and rewrite the destination MAC address. - * </p> - * - * @param dstIpAddress the destination IP address in packet to match - * @param newDstIpAddress the new destination IP address to set - * @param dstMacAddress the destination MAC address to set - * @param dstConnectPoint the egress point - * @param srcConnectPoint the ingress point - * @return a PointToPointIntent - */ - private PointToPointIntent dstMatchIntentGenerator( - IpAddress dstIpAddress, - IpAddress newDstIpAddress, - MacAddress dstMacAddress, - ConnectPoint dstConnectPoint, - ConnectPoint srcConnectPoint) { - checkNotNull(dstIpAddress); - checkNotNull(newDstIpAddress); - checkNotNull(dstMacAddress); - checkNotNull(dstConnectPoint); - checkNotNull(srcConnectPoint); - - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); - selector.matchEthType(Ethernet.TYPE_IPV4); - selector.matchIPDst(IpPrefix.valueOf(dstIpAddress, - IpPrefix.MAX_INET_MASK_LENGTH)); - - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); - treatment.setEthDst(dstMacAddress); - treatment.setIpDst(newDstIpAddress); - - Key key = Key.of(newDstIpAddress.toString() + "MatchDst", appId); - PointToPointIntent intent = PointToPointIntent.builder() - .appId(appId) - .key(key) - .selector(selector.build()) - .treatment(treatment.build()) - .egressPoint(dstConnectPoint) - .ingressPoint(srcConnectPoint) - .build(); - log.info("Generated a PointToPointIntent for traffic to local host " - + ": {}", intent); - - return intent; - } - - /** - * Constructor to store the a vCPE host info. - */ - private class VcpeHost { - MacAddress macAddress; - String hostName; - public VcpeHost(MacAddress macAddress, String hostName) { - this.macAddress = macAddress; - this.hostName = hostName; - } - } -} |