diff options
Diffstat (limited to 'framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive')
4 files changed, 683 insertions, 3 deletions
diff --git a/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/LocationType.java b/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/LocationType.java new file mode 100644 index 00000000..01f4f700 --- /dev/null +++ b/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/LocationType.java @@ -0,0 +1,35 @@ +/* + * 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.reactive.routing; + +/** + * Specifies the type of an IP address or an IP prefix location. + */ +enum LocationType { + /** + * The location of an IP address or an IP prefix is in local SDN network. + */ + LOCAL, + /** + * The location of an IP address or an IP prefix is outside local SDN network. + */ + INTERNET, + /** + * There is no route for this IP address or IP prefix. + */ + NO_ROUTE +} diff --git a/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/ReactiveRoutingFib.java b/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/ReactiveRoutingFib.java new file mode 100644 index 00000000..8e86056e --- /dev/null +++ b/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/ReactiveRoutingFib.java @@ -0,0 +1,395 @@ +/* + * 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.reactive.routing; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Maps; +import org.onlab.packet.Ethernet; +import org.onlab.packet.IpAddress; +import org.onlab.packet.IpPrefix; +import org.onlab.packet.MacAddress; +import org.onlab.packet.VlanId; +import org.onosproject.core.ApplicationId; +import org.onosproject.incubator.net.intf.Interface; +import org.onosproject.incubator.net.intf.InterfaceService; +import org.onosproject.net.ConnectPoint; +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.HostService; +import org.onosproject.net.intent.Constraint; +import org.onosproject.net.intent.Key; +import org.onosproject.net.intent.MultiPointToSinglePointIntent; +import org.onosproject.net.intent.constraint.PartialFailureConstraint; +import org.onosproject.routing.IntentRequestListener; +import org.onosproject.routing.IntentSynchronizationService; +import org.onosproject.routing.config.RoutingConfigurationService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * FIB component for reactive routing intents. + */ +public class ReactiveRoutingFib implements IntentRequestListener { + + private static final int PRIORITY_OFFSET = 100; + private static final int PRIORITY_MULTIPLIER = 5; + protected static final ImmutableList<Constraint> CONSTRAINTS + = ImmutableList.of(new PartialFailureConstraint()); + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final ApplicationId appId; + private final HostService hostService; + private final RoutingConfigurationService configService; + private final InterfaceService interfaceService; + private final IntentSynchronizationService intentSynchronizer; + + private final Map<IpPrefix, MultiPointToSinglePointIntent> routeIntents; + + /** + * Class constructor. + * + * @param appId application ID to use to generate intents + * @param hostService host service + * @param configService routing configuration service + * @param interfaceService interface service + * @param intentSynchronizer intent synchronization service + */ + public ReactiveRoutingFib(ApplicationId appId, HostService hostService, + RoutingConfigurationService configService, + InterfaceService interfaceService, + IntentSynchronizationService intentSynchronizer) { + this.appId = appId; + this.hostService = hostService; + this.configService = configService; + this.interfaceService = interfaceService; + this.intentSynchronizer = intentSynchronizer; + + routeIntents = Maps.newConcurrentMap(); + } + + @Override + public void setUpConnectivityInternetToHost(IpAddress hostIpAddress) { + checkNotNull(hostIpAddress); + Set<ConnectPoint> ingressPoints = + configService.getBgpPeerConnectPoints(); + + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); + + if (hostIpAddress.isIp4()) { + selector.matchEthType(Ethernet.TYPE_IPV4); + } else { + selector.matchEthType(Ethernet.TYPE_IPV6); + } + + // Match the destination IP prefix at the first hop + IpPrefix ipPrefix = hostIpAddress.toIpPrefix(); + selector.matchIPDst(ipPrefix); + + // Rewrite the destination MAC address + MacAddress hostMac = null; + ConnectPoint egressPoint = null; + for (Host host : hostService.getHostsByIp(hostIpAddress)) { + if (host.mac() != null) { + hostMac = host.mac(); + egressPoint = host.location(); + break; + } + } + if (hostMac == null) { + hostService.startMonitoringIp(hostIpAddress); + return; + } + + TrafficTreatment.Builder treatment = + DefaultTrafficTreatment.builder().setEthDst(hostMac); + Key key = Key.of(ipPrefix.toString(), appId); + int priority = ipPrefix.prefixLength() * PRIORITY_MULTIPLIER + + PRIORITY_OFFSET; + MultiPointToSinglePointIntent intent = + MultiPointToSinglePointIntent.builder() + .appId(appId) + .key(key) + .selector(selector.build()) + .treatment(treatment.build()) + .ingressPoints(ingressPoints) + .egressPoint(egressPoint) + .priority(priority) + .constraints(CONSTRAINTS) + .build(); + + log.trace("Generates ConnectivityInternetToHost intent {}", intent); + submitReactiveIntent(ipPrefix, intent); + } + + @Override + public void setUpConnectivityHostToInternet(IpAddress hostIp, IpPrefix prefix, + IpAddress nextHopIpAddress) { + // Find the attachment point (egress interface) of the next hop + Interface egressInterface = interfaceService.getMatchingInterface(nextHopIpAddress); + if (egressInterface == null) { + log.warn("No outgoing interface found for {}", + nextHopIpAddress); + return; + } + + Set<Host> hosts = hostService.getHostsByIp(nextHopIpAddress); + if (hosts.isEmpty()) { + log.warn("No host found for next hop IP address"); + return; + } + MacAddress nextHopMacAddress = null; + for (Host host : hosts) { + nextHopMacAddress = host.mac(); + break; + } + + hosts = hostService.getHostsByIp(hostIp); + if (hosts.isEmpty()) { + log.warn("No host found for host IP address"); + return; + } + Host host = hosts.stream().findFirst().get(); + ConnectPoint ingressPoint = host.location(); + + // Generate the intent itself + ConnectPoint egressPort = egressInterface.connectPoint(); + log.debug("Generating intent for prefix {}, next hop mac {}", + prefix, nextHopMacAddress); + + // Match the destination IP prefix at the first hop + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); + if (prefix.isIp4()) { + selector.matchEthType(Ethernet.TYPE_IPV4); + selector.matchIPDst(prefix); + } else { + selector.matchEthType(Ethernet.TYPE_IPV6); + selector.matchIPv6Dst(prefix); + } + + // Rewrite the destination MAC address + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder() + .setEthDst(nextHopMacAddress); + if (!egressInterface.vlan().equals(VlanId.NONE)) { + treatment.setVlanId(egressInterface.vlan()); + // If we set VLAN ID, we have to make sure a VLAN tag exists. + // TODO support no VLAN -> VLAN routing + selector.matchVlanId(VlanId.ANY); + } + + int priority = prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET; + Key key = Key.of(prefix.toString() + "-reactive", appId); + MultiPointToSinglePointIntent intent = MultiPointToSinglePointIntent.builder() + .appId(appId) + .key(key) + .selector(selector.build()) + .treatment(treatment.build()) + .ingressPoints(Collections.singleton(ingressPoint)) + .egressPoint(egressPort) + .priority(priority) + .constraints(CONSTRAINTS) + .build(); + + submitReactiveIntent(prefix, intent); + } + + @Override + public void setUpConnectivityHostToHost(IpAddress dstIpAddress, + IpAddress srcIpAddress, + MacAddress srcMacAddress, + ConnectPoint srcConnectPoint) { + checkNotNull(dstIpAddress); + checkNotNull(srcIpAddress); + checkNotNull(srcMacAddress); + checkNotNull(srcConnectPoint); + + IpPrefix srcIpPrefix = srcIpAddress.toIpPrefix(); + IpPrefix dstIpPrefix = dstIpAddress.toIpPrefix(); + ConnectPoint dstConnectPoint = null; + MacAddress dstMacAddress = null; + + for (Host host : hostService.getHostsByIp(dstIpAddress)) { + if (host.mac() != null) { + dstMacAddress = host.mac(); + dstConnectPoint = host.location(); + break; + } + } + if (dstMacAddress == null) { + hostService.startMonitoringIp(dstIpAddress); + return; + } + + // + // Handle intent from source host to destination host + // + MultiPointToSinglePointIntent srcToDstIntent = + hostToHostIntentGenerator(dstIpAddress, dstConnectPoint, + dstMacAddress, srcConnectPoint); + submitReactiveIntent(dstIpPrefix, srcToDstIntent); + + // + // Handle intent from destination host to source host + // + + // Since we proactively handle the intent from destination host to + // source host, we should check whether there is an exiting intent + // first. + if (mp2pIntentExists(srcIpPrefix)) { + updateExistingMp2pIntent(srcIpPrefix, dstConnectPoint); + return; + } else { + // There is no existing intent, create a new one. + MultiPointToSinglePointIntent dstToSrcIntent = + hostToHostIntentGenerator(srcIpAddress, srcConnectPoint, + srcMacAddress, dstConnectPoint); + submitReactiveIntent(srcIpPrefix, dstToSrcIntent); + } + } + + /** + * Generates MultiPointToSinglePointIntent for both source host and + * destination host located in local SDN network. + * + * @param dstIpAddress the destination IP address + * @param dstConnectPoint the destination host connect point + * @param dstMacAddress the MAC address of destination host + * @param srcConnectPoint the connect point where packet-in from + * @return the generated MultiPointToSinglePointIntent + */ + private MultiPointToSinglePointIntent hostToHostIntentGenerator( + IpAddress dstIpAddress, + ConnectPoint dstConnectPoint, + MacAddress dstMacAddress, + ConnectPoint srcConnectPoint) { + checkNotNull(dstIpAddress); + checkNotNull(dstConnectPoint); + checkNotNull(dstMacAddress); + checkNotNull(srcConnectPoint); + + Set<ConnectPoint> ingressPoints = new HashSet<>(); + ingressPoints.add(srcConnectPoint); + IpPrefix dstIpPrefix = dstIpAddress.toIpPrefix(); + + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); + if (dstIpAddress.isIp4()) { + selector.matchEthType(Ethernet.TYPE_IPV4); + selector.matchIPDst(dstIpPrefix); + } else { + selector.matchEthType(Ethernet.TYPE_IPV6); + selector.matchIPv6Dst(dstIpPrefix); + } + + // Rewrite the destination MAC address + TrafficTreatment.Builder treatment = + DefaultTrafficTreatment.builder().setEthDst(dstMacAddress); + + Key key = Key.of(dstIpPrefix.toString(), appId); + int priority = dstIpPrefix.prefixLength() * PRIORITY_MULTIPLIER + + PRIORITY_OFFSET; + MultiPointToSinglePointIntent intent = + MultiPointToSinglePointIntent.builder() + .appId(appId) + .key(key) + .selector(selector.build()) + .treatment(treatment.build()) + .ingressPoints(ingressPoints) + .egressPoint(dstConnectPoint) + .priority(priority) + .constraints(CONSTRAINTS) + .build(); + + log.trace("Generates ConnectivityHostToHost = {} ", intent); + return intent; + } + + @Override + public void updateExistingMp2pIntent(IpPrefix ipPrefix, + ConnectPoint ingressConnectPoint) { + checkNotNull(ipPrefix); + checkNotNull(ingressConnectPoint); + + MultiPointToSinglePointIntent existingIntent = + getExistingMp2pIntent(ipPrefix); + if (existingIntent != null) { + Set<ConnectPoint> ingressPoints = existingIntent.ingressPoints(); + // Add host connect point into ingressPoints of the existing intent + if (ingressPoints.add(ingressConnectPoint)) { + MultiPointToSinglePointIntent updatedMp2pIntent = + MultiPointToSinglePointIntent.builder() + .appId(appId) + .key(existingIntent.key()) + .selector(existingIntent.selector()) + .treatment(existingIntent.treatment()) + .ingressPoints(ingressPoints) + .egressPoint(existingIntent.egressPoint()) + .priority(existingIntent.priority()) + .constraints(CONSTRAINTS) + .build(); + + log.trace("Update an existing MultiPointToSinglePointIntent " + + "to new intent = {} ", updatedMp2pIntent); + submitReactiveIntent(ipPrefix, updatedMp2pIntent); + } + // If adding ingressConnectPoint to ingressPoints failed, it + // because between the time interval from checking existing intent + // to generating new intent, onos updated this intent due to other + // packet-in and the new intent also includes the + // ingressConnectPoint. This will not affect reactive routing. + } + } + + /** + * Submits a reactive intent to the intent synchronizer. + * + * @param ipPrefix IP prefix of the intent + * @param intent intent to submit + */ + void submitReactiveIntent(IpPrefix ipPrefix, MultiPointToSinglePointIntent intent) { + routeIntents.put(ipPrefix, intent); + + intentSynchronizer.submit(intent); + } + + /** + * Gets the existing MultiPointToSinglePointIntent from memory for a given + * IP prefix. + * + * @param ipPrefix the IP prefix used to find MultiPointToSinglePointIntent + * @return the MultiPointToSinglePointIntent if found, otherwise null + */ + private MultiPointToSinglePointIntent getExistingMp2pIntent(IpPrefix ipPrefix) { + checkNotNull(ipPrefix); + return routeIntents.get(ipPrefix); + } + + @Override + public boolean mp2pIntentExists(IpPrefix ipPrefix) { + checkNotNull(ipPrefix); + return routeIntents.get(ipPrefix) != null; + } +} diff --git a/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java b/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java index ad78a1ce..96aa06ee 100644 --- a/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java +++ b/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java @@ -25,27 +25,39 @@ import org.onlab.packet.EthType; import org.onlab.packet.Ethernet; import org.onlab.packet.IPv4; import org.onlab.packet.Ip4Address; +import org.onlab.packet.Ip6Address; 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.incubator.net.intf.Interface; +import org.onosproject.incubator.net.intf.InterfaceService; import org.onosproject.net.ConnectPoint; +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.HostService; import org.onosproject.net.packet.DefaultOutboundPacket; import org.onosproject.net.packet.InboundPacket; import org.onosproject.net.packet.OutboundPacket; import org.onosproject.net.packet.PacketContext; import org.onosproject.net.packet.PacketProcessor; import org.onosproject.net.packet.PacketService; +import org.onosproject.routing.IntentRequestListener; +import org.onosproject.routing.RouteEntry; import org.onosproject.routing.RoutingService; +import org.onosproject.routing.SdnIpService; import org.onosproject.routing.config.RoutingConfigurationService; import org.slf4j.Logger; import java.nio.ByteBuffer; +import java.util.Optional; +import java.util.Set; +import static com.google.common.base.Preconditions.checkNotNull; import static org.onlab.packet.Ethernet.TYPE_ARP; import static org.onlab.packet.Ethernet.TYPE_IPV4; import static org.onosproject.net.packet.PacketPriority.REACTIVE; @@ -74,16 +86,32 @@ public class SdnIpReactiveRouting { protected RoutingService routingService; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected SdnIpService sdnIpService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected RoutingConfigurationService config; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected InterfaceService interfaceService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected HostService hostService; + private ApplicationId appId; + private IntentRequestListener intentRequestListener; + private ReactiveRoutingProcessor processor = new ReactiveRoutingProcessor(); @Activate public void activate() { appId = coreService.registerApplication(APP_NAME); + + intentRequestListener = new ReactiveRoutingFib(appId, hostService, + config, interfaceService, + sdnIpService.getIntentSynchronizationService()); + packetService.addProcessor(processor, PacketProcessor.director(2)); requestIntercepts(); log.info("SDN-IP Reactive Routing Started"); @@ -168,12 +196,11 @@ public class SdnIpReactiveRouting { IpAddress srcIp = IpAddress.valueOf(ipv4Packet.getSourceAddress()); MacAddress srcMac = ethPkt.getSourceMAC(); - routingService.packetReactiveProcessor(dstIp, srcIp, - srcConnectPoint, srcMac); + packetReactiveProcessor(dstIp, srcIp, srcConnectPoint, srcMac); // TODO emit packet first or packetReactiveProcessor first ConnectPoint egressConnectPoint = null; - egressConnectPoint = routingService.getEgressConnectPoint(dstIp); + egressConnectPoint = getEgressConnectPoint(dstIp); if (egressConnectPoint != null) { forwardPacketToDst(context, egressConnectPoint); } @@ -185,6 +212,173 @@ public class SdnIpReactiveRouting { } /** + * Routes packet reactively. + * + * @param dstIpAddress the destination IP address of a packet + * @param srcIpAddress the source IP address of a packet + * @param srcConnectPoint the connect point where a packet comes from + * @param srcMacAddress the source MAC address of a packet + */ + private void packetReactiveProcessor(IpAddress dstIpAddress, + IpAddress srcIpAddress, + ConnectPoint srcConnectPoint, + MacAddress srcMacAddress) { + checkNotNull(dstIpAddress); + checkNotNull(srcIpAddress); + checkNotNull(srcConnectPoint); + checkNotNull(srcMacAddress); + + // + // Step1: Try to update the existing intent first if it exists. + // + IpPrefix ipPrefix = null; + RouteEntry routeEntry = null; + if (config.isIpAddressLocal(dstIpAddress)) { + if (dstIpAddress.isIp4()) { + ipPrefix = IpPrefix.valueOf(dstIpAddress, + Ip4Address.BIT_LENGTH); + } else { + ipPrefix = IpPrefix.valueOf(dstIpAddress, + Ip6Address.BIT_LENGTH); + } + } else { + // Get IP prefix from BGP route table + routeEntry = routingService.getLongestMatchableRouteEntry(dstIpAddress); + if (routeEntry != null) { + ipPrefix = routeEntry.prefix(); + } + } + if (ipPrefix != null + && intentRequestListener.mp2pIntentExists(ipPrefix)) { + intentRequestListener.updateExistingMp2pIntent(ipPrefix, + srcConnectPoint); + return; + } + + // + // Step2: There is no existing intent for the destination IP address. + // Check whether it is necessary to create a new one. If necessary then + // create a new one. + // + TrafficType trafficType = + trafficTypeClassifier(srcConnectPoint, dstIpAddress); + + switch (trafficType) { + case HOST_TO_INTERNET: + // If the destination IP address is outside the local SDN network. + // The Step 1 has already handled it. We do not need to do anything here. + intentRequestListener.setUpConnectivityHostToInternet(srcIpAddress, + ipPrefix, routeEntry.nextHop()); + break; + case INTERNET_TO_HOST: + intentRequestListener.setUpConnectivityInternetToHost(dstIpAddress); + break; + case HOST_TO_HOST: + intentRequestListener.setUpConnectivityHostToHost(dstIpAddress, + srcIpAddress, srcMacAddress, srcConnectPoint); + break; + case INTERNET_TO_INTERNET: + log.trace("This is transit traffic, " + + "the intent should be preinstalled already"); + break; + case DROP: + // TODO here should setUpDropPacketIntent(...); + // We need a new type of intent here. + break; + case UNKNOWN: + log.trace("This is unknown traffic, so we do nothing"); + break; + default: + break; + } + } + + /** + * Classifies the traffic and return the traffic type. + * + * @param srcConnectPoint the connect point where the packet comes from + * @param dstIp the destination IP address in packet + * @return the traffic type which this packet belongs to + */ + private TrafficType trafficTypeClassifier(ConnectPoint srcConnectPoint, + IpAddress dstIp) { + LocationType dstIpLocationType = getLocationType(dstIp); + Optional<Interface> srcInterface = + interfaceService.getInterfacesByPort(srcConnectPoint).stream().findFirst(); + Set<ConnectPoint> ingressPoints = config.getBgpPeerConnectPoints(); + + switch (dstIpLocationType) { + case INTERNET: + if (srcInterface.isPresent() && + (!ingressPoints.contains(srcConnectPoint))) { + return TrafficType.HOST_TO_INTERNET; + } else { + return TrafficType.INTERNET_TO_INTERNET; + } + case LOCAL: + if (srcInterface.isPresent() && + (!ingressPoints.contains(srcConnectPoint))) { + return TrafficType.HOST_TO_HOST; + } else { + // TODO Currently we only consider local public prefixes. + // In the future, we will consider the local private prefixes. + // If dstIpLocationType is a local private, we should return + // TrafficType.DROP. + return TrafficType.INTERNET_TO_HOST; + } + case NO_ROUTE: + return TrafficType.DROP; + default: + return TrafficType.UNKNOWN; + } + } + + /** + * Evaluates the location of an IP address and returns the location type. + * + * @param ipAddress the IP address to evaluate + * @return the IP address location type + */ + private LocationType getLocationType(IpAddress ipAddress) { + if (config.isIpAddressLocal(ipAddress)) { + return LocationType.LOCAL; + } else if (routingService.getLongestMatchableRouteEntry(ipAddress) != null) { + return LocationType.INTERNET; + } else { + return LocationType.NO_ROUTE; + } + } + + public ConnectPoint getEgressConnectPoint(IpAddress dstIpAddress) { + LocationType type = getLocationType(dstIpAddress); + if (type == LocationType.LOCAL) { + Set<Host> hosts = hostService.getHostsByIp(dstIpAddress); + if (!hosts.isEmpty()) { + return hosts.iterator().next().location(); + } else { + hostService.startMonitoringIp(dstIpAddress); + return null; + } + } else if (type == LocationType.INTERNET) { + IpAddress nextHopIpAddress = null; + RouteEntry routeEntry = routingService.getLongestMatchableRouteEntry(dstIpAddress); + if (routeEntry != null) { + nextHopIpAddress = routeEntry.nextHop(); + Interface it = interfaceService.getMatchingInterface(nextHopIpAddress); + if (it != null) { + return it.connectPoint(); + } else { + return null; + } + } else { + return null; + } + } else { + return null; + } + } + + /** * Emits the specified packet onto the network. * * @param context the packet context diff --git a/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/TrafficType.java b/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/TrafficType.java new file mode 100644 index 00000000..134126b3 --- /dev/null +++ b/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/TrafficType.java @@ -0,0 +1,56 @@ +/* + * 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.reactive.routing; + +/** + * Specifies the type of traffic. + * <p> + * We classify traffic by the first packet of each traffic. + * </p> + */ +enum TrafficType { + /** + * Traffic from a host located in local SDN network wants to + * communicate with destination host located in Internet (outside + * local SDN network). + */ + HOST_TO_INTERNET, + /** + * Traffic from Internet wants to communicate with a host located + * in local SDN network. + */ + INTERNET_TO_HOST, + /** + * Both the source host and destination host of a traffic are in + * local SDN network. + */ + HOST_TO_HOST, + /** + * Traffic from Internet wants to traverse local SDN network. + */ + INTERNET_TO_INTERNET, + /** + * Any traffic wants to communicate with a destination which has + * no route, or traffic from Internet wants to access a local private + * IP address. + */ + DROP, + /** + * Traffic does not belong to the types above. + */ + UNKNOWN +} |