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/proxyarp/pom.xml | 45 ++++ .../java/org/onosproject/proxyarp/ProxyArp.java | 240 +++++++++++++++++++++ .../org/onosproject/proxyarp/package-info.java | 20 ++ 3 files changed, 305 insertions(+) create mode 100644 framework/src/onos/apps/proxyarp/pom.xml create mode 100644 framework/src/onos/apps/proxyarp/src/main/java/org/onosproject/proxyarp/ProxyArp.java create mode 100644 framework/src/onos/apps/proxyarp/src/main/java/org/onosproject/proxyarp/package-info.java (limited to 'framework/src/onos/apps/proxyarp') diff --git a/framework/src/onos/apps/proxyarp/pom.xml b/framework/src/onos/apps/proxyarp/pom.xml new file mode 100644 index 00000000..e6e76585 --- /dev/null +++ b/framework/src/onos/apps/proxyarp/pom.xml @@ -0,0 +1,45 @@ + + + + 4.0.0 + + + org.onosproject + onos-apps + 1.3.0-SNAPSHOT + ../pom.xml + + + onos-app-proxyarp + bundle + + Proxy ARP/NDP application + + + org.onosproject.proxyarp + + + + + org.osgi + org.osgi.compendium + + + + diff --git a/framework/src/onos/apps/proxyarp/src/main/java/org/onosproject/proxyarp/ProxyArp.java b/framework/src/onos/apps/proxyarp/src/main/java/org/onosproject/proxyarp/ProxyArp.java new file mode 100644 index 00000000..742d7af7 --- /dev/null +++ b/framework/src/onos/apps/proxyarp/src/main/java/org/onosproject/proxyarp/ProxyArp.java @@ -0,0 +1,240 @@ +/* + * Copyright 2014-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.proxyarp; + +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.Modified; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onlab.packet.Ethernet; +import org.onosproject.cfg.ComponentConfigService; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.packet.InboundPacket; +import org.onosproject.net.packet.PacketContext; +import org.onosproject.net.packet.PacketProcessor; +import org.onosproject.net.packet.PacketService; +import org.onosproject.net.proxyarp.ProxyArpService; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; + +import java.util.Dictionary; + +import static com.google.common.base.Strings.isNullOrEmpty; +import static org.onlab.packet.Ethernet.TYPE_ARP; +import static org.onlab.packet.Ethernet.TYPE_IPV6; +import static org.onlab.packet.ICMP6.NEIGHBOR_ADVERTISEMENT; +import static org.onlab.packet.ICMP6.NEIGHBOR_SOLICITATION; +import static org.onlab.packet.IPv6.PROTOCOL_ICMP6; +import static org.onosproject.net.packet.PacketPriority.CONTROL; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Sample reactive proxy arp application. + */ +@Component(immediate = true) +public class ProxyArp { + + private final Logger log = getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PacketService packetService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected ProxyArpService proxyArpService; + + private ProxyArpProcessor processor = new ProxyArpProcessor(); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected ComponentConfigService cfgService; + + private ApplicationId appId; + + @Property(name = "ipv6NeighborDiscovery", boolValue = false, + label = "Enable IPv6 Neighbor Discovery; default is false") + protected boolean ipv6NeighborDiscovery = false; + + @Activate + public void activate(ComponentContext context) { + cfgService.registerProperties(getClass()); + appId = coreService.registerApplication("org.onosproject.proxyarp"); + + packetService.addProcessor(processor, PacketProcessor.director(1)); + readComponentConfiguration(context); + requestPackests(); + + log.info("Started with Application ID {}", appId.id()); + } + + @Deactivate + public void deactivate() { + cfgService.unregisterProperties(getClass(), false); + withdrawIntercepts(); + packetService.removeProcessor(processor); + processor = null; + log.info("Stopped"); + } + + @Modified + public void modified(ComponentContext context) { + readComponentConfiguration(context); + requestPackests(); + } + + /** + * Request packet in via PacketService. + */ + private void requestPackests() { + TrafficSelector.Builder selectorBuilder = + DefaultTrafficSelector.builder(); + selectorBuilder.matchEthType(TYPE_ARP); + packetService.requestPackets(selectorBuilder.build(), + CONTROL, appId); + + selectorBuilder = DefaultTrafficSelector.builder(); + selectorBuilder.matchEthType(TYPE_IPV6); + selectorBuilder.matchIPProtocol(PROTOCOL_ICMP6); + selectorBuilder.matchIcmpv6Type(NEIGHBOR_SOLICITATION); + if (ipv6NeighborDiscovery) { + // IPv6 Neighbor Solicitation packet. + packetService.requestPackets(selectorBuilder.build(), + CONTROL, appId); + } else { + packetService.cancelPackets(selectorBuilder.build(), + CONTROL, appId); + } + + // IPv6 Neighbor Advertisement packet. + selectorBuilder = DefaultTrafficSelector.builder(); + selectorBuilder.matchEthType(TYPE_IPV6); + selectorBuilder.matchIPProtocol(PROTOCOL_ICMP6); + selectorBuilder.matchIcmpv6Type(NEIGHBOR_ADVERTISEMENT); + if (ipv6NeighborDiscovery) { + packetService.requestPackets(selectorBuilder.build(), + CONTROL, appId); + } else { + packetService.cancelPackets(selectorBuilder.build(), + CONTROL, appId); + } + + + } + + /** + * Cancel requested packet in via packet service. + */ + private void withdrawIntercepts() { + TrafficSelector.Builder selectorBuilder = + DefaultTrafficSelector.builder(); + selectorBuilder.matchEthType(TYPE_ARP); + packetService.cancelPackets(selectorBuilder.build(), CONTROL, appId); + selectorBuilder = DefaultTrafficSelector.builder(); + selectorBuilder.matchEthType(TYPE_IPV6); + selectorBuilder.matchIPProtocol(PROTOCOL_ICMP6); + selectorBuilder.matchIcmpv6Type(NEIGHBOR_SOLICITATION); + packetService.cancelPackets(selectorBuilder.build(), CONTROL, appId); + selectorBuilder = DefaultTrafficSelector.builder(); + selectorBuilder.matchEthType(TYPE_IPV6); + selectorBuilder.matchIPProtocol(PROTOCOL_ICMP6); + selectorBuilder.matchIcmpv6Type(NEIGHBOR_ADVERTISEMENT); + packetService.cancelPackets(selectorBuilder.build(), CONTROL, appId); + + } + + /** + * Extracts properties from the component configuration context. + * + * @param context the component context + */ + private void readComponentConfiguration(ComponentContext context) { + Dictionary properties = context.getProperties(); + Boolean flag; + + flag = isPropertyEnabled(properties, "ipv6NeighborDiscovery"); + if (flag == null) { + log.info("IPv6 Neighbor Discovery is not configured, " + + "using current value of {}", ipv6NeighborDiscovery); + } else { + ipv6NeighborDiscovery = flag; + log.info("Configured. IPv6 Neighbor Discovery is {}", + ipv6NeighborDiscovery ? "enabled" : "disabled"); + } + } + + /** + * Check property name is defined and set to true. + * + * @param properties properties to be looked up + * @param propertyName the name of the property to look up + * @return value when the propertyName is defined or return null + */ + private static Boolean isPropertyEnabled(Dictionary properties, + String propertyName) { + Boolean value = null; + try { + String s = (String) properties.get(propertyName); + value = isNullOrEmpty(s) ? null : s.trim().equals("true"); + } catch (ClassCastException e) { + // No propertyName defined. + value = null; + } + return value; + } + + /** + * Packet processor responsible for forwarding packets along their paths. + */ + private class ProxyArpProcessor implements PacketProcessor { + + @Override + public void process(PacketContext context) { + // Stop processing if the packet has been handled, since we + // can't do any more to it. + if (context.isHandled()) { + return; + } + // If IPv6 NDP is disabled, don't handle IPv6 frames. + InboundPacket pkt = context.inPacket(); + Ethernet ethPkt = pkt.parsed(); + if (ethPkt == null) { + return; + } + if (!ipv6NeighborDiscovery && (ethPkt.getEtherType() == TYPE_IPV6)) { + return; + } + + // Do not ARP for multicast packets. Let mfwd handle them. + if (ethPkt.getEtherType() == Ethernet.TYPE_IPV4) { + if (ethPkt.getDestinationMAC().isMulticast()) { + return; + } + } + + //handle the arp packet. + proxyArpService.handlePacket(context); + } + } +} + + diff --git a/framework/src/onos/apps/proxyarp/src/main/java/org/onosproject/proxyarp/package-info.java b/framework/src/onos/apps/proxyarp/src/main/java/org/onosproject/proxyarp/package-info.java new file mode 100644 index 00000000..812a7510 --- /dev/null +++ b/framework/src/onos/apps/proxyarp/src/main/java/org/onosproject/proxyarp/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 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. + */ + +/** + * Proxy Arp application that handles arp resolution for you. + */ +package org.onosproject.proxyarp; -- cgit 1.2.3-korg