From 13d05bc8458758ee39cb829098241e89616717ee Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Wed, 9 Sep 2015 22:15:21 -0700 Subject: ONOS checkin based on commit tag e796610b1f721d02f9b0e213cf6f7790c10ecd60 Change-Id: Ife8810491034fe7becdba75dda20de4267bd15cd --- framework/src/onos/apps/reactive-routing/pom.xml | 52 ++++++ .../reactive/routing/SdnIpReactiveRouting.java | 206 +++++++++++++++++++++ .../onosproject/reactive/routing/package-info.java | 21 +++ 3 files changed, 279 insertions(+) create mode 100644 framework/src/onos/apps/reactive-routing/pom.xml create mode 100644 framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java create mode 100644 framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/package-info.java (limited to 'framework/src/onos/apps/reactive-routing') diff --git a/framework/src/onos/apps/reactive-routing/pom.xml b/framework/src/onos/apps/reactive-routing/pom.xml new file mode 100644 index 00000000..1d93cbf1 --- /dev/null +++ b/framework/src/onos/apps/reactive-routing/pom.xml @@ -0,0 +1,52 @@ + + + + 4.0.0 + + + org.onosproject + onos-apps + 1.3.0-SNAPSHOT + ../pom.xml + + + onos-app-reactive-routing + bundle + + SDN-IP reactive routing application + + + org.onosproject.reactive.routing + + + + + org.onosproject + onos-app-routing-api + ${project.version} + + + + org.onosproject + onos-app-routing + ${project.version} + + + + \ No newline at end of file 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 new file mode 100644 index 00000000..ad78a1ce --- /dev/null +++ b/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java @@ -0,0 +1,206 @@ +/* + * 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 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.onlab.packet.ARP; +import org.onlab.packet.EthType; +import org.onlab.packet.Ethernet; +import org.onlab.packet.IPv4; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.ConnectPoint; +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.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.RoutingService; +import org.onosproject.routing.config.RoutingConfigurationService; +import org.slf4j.Logger; + +import java.nio.ByteBuffer; + +import static org.onlab.packet.Ethernet.TYPE_ARP; +import static org.onlab.packet.Ethernet.TYPE_IPV4; +import static org.onosproject.net.packet.PacketPriority.REACTIVE; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * This is reactive routing to handle 3 cases: + * (1) one host wants to talk to another host, both two hosts are in + * SDN network. + * (2) one host in SDN network wants to talk to another host in Internet. + * (3) one host from Internet wants to talk to another host in SDN network. + */ +@Component(immediate = true) +public class SdnIpReactiveRouting { + + private static final String APP_NAME = "org.onosproject.reactive.routing"; + private final Logger log = getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PacketService packetService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected RoutingService routingService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected RoutingConfigurationService config; + + private ApplicationId appId; + + private ReactiveRoutingProcessor processor = + new ReactiveRoutingProcessor(); + + @Activate + public void activate() { + appId = coreService.registerApplication(APP_NAME); + packetService.addProcessor(processor, PacketProcessor.director(2)); + requestIntercepts(); + log.info("SDN-IP Reactive Routing Started"); + } + + @Deactivate + public void deactivate() { + withdrawIntercepts(); + packetService.removeProcessor(processor); + processor = null; + log.info("SDN-IP Reactive Routing Stopped"); + } + + /** + * Request packet in via the PacketService. + */ + private void requestIntercepts() { + //TODO: to support IPv6 later + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); + selector.matchEthType(TYPE_IPV4); + packetService.requestPackets(selector.build(), REACTIVE, appId); + selector.matchEthType(TYPE_ARP); + packetService.requestPackets(selector.build(), REACTIVE, appId); + } + + /** + * Cancel request for packet in via PacketService. + */ + private void withdrawIntercepts() { + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); + selector.matchEthType(TYPE_IPV4); + packetService.cancelPackets(selector.build(), REACTIVE, appId); + selector = DefaultTrafficSelector.builder(); + selector.matchEthType(TYPE_ARP); + packetService.cancelPackets(selector.build(), REACTIVE, appId); + } + + private class ReactiveRoutingProcessor implements PacketProcessor { + @Override + public void process(PacketContext context) { + + InboundPacket pkt = context.inPacket(); + Ethernet ethPkt = pkt.parsed(); + if (ethPkt == null) { + return; + } + ConnectPoint srcConnectPoint = pkt.receivedFrom(); + + switch (EthType.EtherType.lookup(ethPkt.getEtherType())) { + case ARP: + ARP arpPacket = (ARP) ethPkt.getPayload(); + Ip4Address targetIpAddress = Ip4Address + .valueOf(arpPacket.getTargetProtocolAddress()); + // Only when it is an ARP request packet and the target IP + // address is a virtual gateway IP address, then it will be + // processed. + if (arpPacket.getOpCode() == ARP.OP_REQUEST + && config.isVirtualGatewayIpAddress(targetIpAddress)) { + MacAddress gatewayMacAddress = + config.getVirtualGatewayMacAddress(); + if (gatewayMacAddress == null) { + break; + } + Ethernet eth = ARP.buildArpReply(targetIpAddress, + gatewayMacAddress, + ethPkt); + + TrafficTreatment.Builder builder = + DefaultTrafficTreatment.builder(); + builder.setOutput(srcConnectPoint.port()); + packetService.emit(new DefaultOutboundPacket( + srcConnectPoint.deviceId(), + builder.build(), + ByteBuffer.wrap(eth.serialize()))); + } + break; + case IPV4: + // Parse packet + IPv4 ipv4Packet = (IPv4) ethPkt.getPayload(); + IpAddress dstIp = + IpAddress.valueOf(ipv4Packet.getDestinationAddress()); + IpAddress srcIp = + IpAddress.valueOf(ipv4Packet.getSourceAddress()); + MacAddress srcMac = ethPkt.getSourceMAC(); + routingService.packetReactiveProcessor(dstIp, srcIp, + srcConnectPoint, srcMac); + + // TODO emit packet first or packetReactiveProcessor first + ConnectPoint egressConnectPoint = null; + egressConnectPoint = routingService.getEgressConnectPoint(dstIp); + if (egressConnectPoint != null) { + forwardPacketToDst(context, egressConnectPoint); + } + break; + default: + break; + } + } + } + + /** + * Emits the specified packet onto the network. + * + * @param context the packet context + * @param connectPoint the connect point where the packet should be + * sent out + */ + private void forwardPacketToDst(PacketContext context, + ConnectPoint connectPoint) { + TrafficTreatment treatment = DefaultTrafficTreatment.builder() + .setOutput(connectPoint.port()).build(); + OutboundPacket packet = + new DefaultOutboundPacket(connectPoint.deviceId(), treatment, + context.inPacket().unparsed()); + packetService.emit(packet); + log.trace("sending packet: {}", packet); + } + +} + diff --git a/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/package-info.java b/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/package-info.java new file mode 100644 index 00000000..87c8fc84 --- /dev/null +++ b/framework/src/onos/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +/** + * Application to enable (1) hosts in local SDN network to talk to other hosts + * in Internet, and (2) hosts in local SDN network to talk to each other. + */ +package org.onosproject.reactive.routing; -- cgit 1.2.3-korg