diff options
author | CNlucius <lukai1@huawei.com> | 2016-09-13 11:40:12 +0800 |
---|---|---|
committer | CNlucius <lukai1@huawei.com> | 2016-09-13 11:41:53 +0800 |
commit | b731e2f1dd0972409b136aebc7b463dd72c9cfad (patch) | |
tree | 5107d7d80c19ad8076c2c97c2b5ef8d1cf3ab903 /framework/src/onos/apps/fwd | |
parent | ee93993458266114c29271a481ef9ce7ce621b2a (diff) |
ONOSFW-171
O/S-SFC-ONOS scenario documentation
Change-Id: I51ae1cf736ea24ab6680f8edca1b2bf5dd598365
Signed-off-by: CNlucius <lukai1@huawei.com>
Diffstat (limited to 'framework/src/onos/apps/fwd')
3 files changed, 0 insertions, 909 deletions
diff --git a/framework/src/onos/apps/fwd/pom.xml b/framework/src/onos/apps/fwd/pom.xml deleted file mode 100644 index 78601300..00000000 --- a/framework/src/onos/apps/fwd/pom.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ 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. - --> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.onosproject</groupId> - <artifactId>onos-apps</artifactId> - <version>1.4.0-rc1</version> - <relativePath>../pom.xml</relativePath> - </parent> - - <artifactId>onos-app-fwd</artifactId> - <packaging>bundle</packaging> - - <description>Reactive forwarding application using flow subsystem</description> - - <properties> - <onos.app.name>org.onosproject.fwd</onos.app.name> - </properties> - - <dependencies> - <dependency> - <groupId>org.osgi</groupId> - <artifactId>org.osgi.compendium</artifactId> - </dependency> - </dependencies> - -</project> diff --git a/framework/src/onos/apps/fwd/src/main/java/org/onosproject/fwd/ReactiveForwarding.java b/framework/src/onos/apps/fwd/src/main/java/org/onosproject/fwd/ReactiveForwarding.java deleted file mode 100644 index 8540ba14..00000000 --- a/framework/src/onos/apps/fwd/src/main/java/org/onosproject/fwd/ReactiveForwarding.java +++ /dev/null @@ -1,844 +0,0 @@ -/* - * 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.fwd; - -import com.google.common.collect.ImmutableSet; -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.onlab.packet.ICMP; -import org.onlab.packet.ICMP6; -import org.onlab.packet.IPv4; -import org.onlab.packet.IPv6; -import org.onlab.packet.Ip4Prefix; -import org.onlab.packet.Ip6Prefix; -import org.onlab.packet.MacAddress; -import org.onlab.packet.TCP; -import org.onlab.packet.TpPort; -import org.onlab.packet.UDP; -import org.onlab.packet.VlanId; -import org.onosproject.cfg.ComponentConfigService; -import org.onosproject.core.ApplicationId; -import org.onosproject.core.CoreService; -import org.onosproject.event.Event; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.DeviceId; -import org.onosproject.net.Host; -import org.onosproject.net.HostId; -import org.onosproject.net.Link; -import org.onosproject.net.Path; -import org.onosproject.net.PortNumber; -import org.onosproject.net.flow.DefaultTrafficSelector; -import org.onosproject.net.flow.DefaultTrafficTreatment; -import org.onosproject.net.flow.FlowEntry; -import org.onosproject.net.flow.FlowRule; -import org.onosproject.net.flow.FlowRuleService; -import org.onosproject.net.flow.TrafficSelector; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.flow.criteria.Criterion; -import org.onosproject.net.flow.criteria.EthCriterion; -import org.onosproject.net.flow.instructions.Instruction; -import org.onosproject.net.flow.instructions.Instructions; -import org.onosproject.net.flowobjective.DefaultForwardingObjective; -import org.onosproject.net.flowobjective.FlowObjectiveService; -import org.onosproject.net.flowobjective.ForwardingObjective; -import org.onosproject.net.host.HostService; -import org.onosproject.net.link.LinkEvent; -import org.onosproject.net.packet.InboundPacket; -import org.onosproject.net.packet.PacketContext; -import org.onosproject.net.packet.PacketPriority; -import org.onosproject.net.packet.PacketProcessor; -import org.onosproject.net.packet.PacketService; -import org.onosproject.net.topology.TopologyEvent; -import org.onosproject.net.topology.TopologyListener; -import org.onosproject.net.topology.TopologyService; -import org.osgi.service.component.ComponentContext; -import org.slf4j.Logger; - -import java.util.Dictionary; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -import static com.google.common.base.Strings.isNullOrEmpty; -import static org.slf4j.LoggerFactory.getLogger; - -/** - * Sample reactive forwarding application. - */ -@Component(immediate = true) -public class ReactiveForwarding { - - private static final int DEFAULT_TIMEOUT = 10; - private static final int DEFAULT_PRIORITY = 10; - - private final Logger log = getLogger(getClass()); - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected TopologyService topologyService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected PacketService packetService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected HostService hostService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected FlowRuleService flowRuleService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected FlowObjectiveService flowObjectiveService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected CoreService coreService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected ComponentConfigService cfgService; - - private ReactivePacketProcessor processor = new ReactivePacketProcessor(); - - private ApplicationId appId; - - @Property(name = "packetOutOnly", boolValue = false, - label = "Enable packet-out only forwarding; default is false") - private boolean packetOutOnly = false; - - @Property(name = "packetOutOfppTable", boolValue = false, - label = "Enable first packet forwarding using OFPP_TABLE port " + - "instead of PacketOut with actual port; default is false") - private boolean packetOutOfppTable = false; - - @Property(name = "flowTimeout", intValue = DEFAULT_TIMEOUT, - label = "Configure Flow Timeout for installed flow rules; " + - "default is 10 sec") - private int flowTimeout = DEFAULT_TIMEOUT; - - @Property(name = "flowPriority", intValue = DEFAULT_PRIORITY, - label = "Configure Flow Priority for installed flow rules; " + - "default is 10") - private int flowPriority = DEFAULT_PRIORITY; - - @Property(name = "ipv6Forwarding", boolValue = false, - label = "Enable IPv6 forwarding; default is false") - private boolean ipv6Forwarding = false; - - @Property(name = "matchDstMacOnly", boolValue = false, - label = "Enable matching Dst Mac Only; default is false") - private boolean matchDstMacOnly = false; - - @Property(name = "matchVlanId", boolValue = false, - label = "Enable matching Vlan ID; default is false") - private boolean matchVlanId = false; - - @Property(name = "matchIpv4Address", boolValue = false, - label = "Enable matching IPv4 Addresses; default is false") - private boolean matchIpv4Address = false; - - @Property(name = "matchIpv4Dscp", boolValue = false, - label = "Enable matching IPv4 DSCP and ECN; default is false") - private boolean matchIpv4Dscp = false; - - @Property(name = "matchIpv6Address", boolValue = false, - label = "Enable matching IPv6 Addresses; default is false") - private boolean matchIpv6Address = false; - - @Property(name = "matchIpv6FlowLabel", boolValue = false, - label = "Enable matching IPv6 FlowLabel; default is false") - private boolean matchIpv6FlowLabel = false; - - @Property(name = "matchTcpUdpPorts", boolValue = false, - label = "Enable matching TCP/UDP ports; default is false") - private boolean matchTcpUdpPorts = false; - - @Property(name = "matchIcmpFields", boolValue = false, - label = "Enable matching ICMPv4 and ICMPv6 fields; " + - "default is false") - private boolean matchIcmpFields = false; - - - @Property(name = "ignoreIPv4Multicast", boolValue = false, - label = "Ignore (do not forward) IPv4 multicast packets; default is false") - private boolean ignoreIpv4McastPackets = false; - - private final TopologyListener topologyListener = new InternalTopologyListener(); - - - @Activate - public void activate(ComponentContext context) { - cfgService.registerProperties(getClass()); - appId = coreService.registerApplication("org.onosproject.fwd"); - - packetService.addProcessor(processor, PacketProcessor.director(2)); - topologyService.addListener(topologyListener); - readComponentConfiguration(context); - requestIntercepts(); - - log.info("Started", appId.id()); - } - - @Deactivate - public void deactivate() { - cfgService.unregisterProperties(getClass(), false); - withdrawIntercepts(); - flowRuleService.removeFlowRulesById(appId); - packetService.removeProcessor(processor); - topologyService.removeListener(topologyListener); - processor = null; - log.info("Stopped"); - } - - @Modified - public void modified(ComponentContext context) { - readComponentConfiguration(context); - requestIntercepts(); - } - - /** - * Request packet in via packet service. - */ - private void requestIntercepts() { - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); - selector.matchEthType(Ethernet.TYPE_IPV4); - packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId); - selector.matchEthType(Ethernet.TYPE_ARP); - packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId); - - selector.matchEthType(Ethernet.TYPE_IPV6); - if (ipv6Forwarding) { - packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId); - } else { - packetService.cancelPackets(selector.build(), PacketPriority.REACTIVE, appId); - } - } - - /** - * Cancel request for packet in via packet service. - */ - private void withdrawIntercepts() { - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); - selector.matchEthType(Ethernet.TYPE_IPV4); - packetService.cancelPackets(selector.build(), PacketPriority.REACTIVE, appId); - selector.matchEthType(Ethernet.TYPE_ARP); - packetService.cancelPackets(selector.build(), PacketPriority.REACTIVE, appId); - selector.matchEthType(Ethernet.TYPE_IPV6); - packetService.cancelPackets(selector.build(), PacketPriority.REACTIVE, appId); - } - - /** - * Extracts properties from the component configuration context. - * - * @param context the component context - */ - private void readComponentConfiguration(ComponentContext context) { - Dictionary<?, ?> properties = context.getProperties(); - boolean packetOutOnlyEnabled = - isPropertyEnabled(properties, "packetOutOnly"); - if (packetOutOnly != packetOutOnlyEnabled) { - packetOutOnly = packetOutOnlyEnabled; - log.info("Configured. Packet-out only forwarding is {}", - packetOutOnly ? "enabled" : "disabled"); - } - boolean packetOutOfppTableEnabled = - isPropertyEnabled(properties, "packetOutOfppTable"); - if (packetOutOfppTable != packetOutOfppTableEnabled) { - packetOutOfppTable = packetOutOfppTableEnabled; - log.info("Configured. Forwarding using OFPP_TABLE port is {}", - packetOutOfppTable ? "enabled" : "disabled"); - } - boolean ipv6ForwardingEnabled = - isPropertyEnabled(properties, "ipv6Forwarding"); - if (ipv6Forwarding != ipv6ForwardingEnabled) { - ipv6Forwarding = ipv6ForwardingEnabled; - log.info("Configured. IPv6 forwarding is {}", - ipv6Forwarding ? "enabled" : "disabled"); - } - boolean matchDstMacOnlyEnabled = - isPropertyEnabled(properties, "matchDstMacOnly"); - if (matchDstMacOnly != matchDstMacOnlyEnabled) { - matchDstMacOnly = matchDstMacOnlyEnabled; - log.info("Configured. Match Dst MAC Only is {}", - matchDstMacOnly ? "enabled" : "disabled"); - } - boolean matchVlanIdEnabled = - isPropertyEnabled(properties, "matchVlanId"); - if (matchVlanId != matchVlanIdEnabled) { - matchVlanId = matchVlanIdEnabled; - log.info("Configured. Matching Vlan ID is {}", - matchVlanId ? "enabled" : "disabled"); - } - boolean matchIpv4AddressEnabled = - isPropertyEnabled(properties, "matchIpv4Address"); - if (matchIpv4Address != matchIpv4AddressEnabled) { - matchIpv4Address = matchIpv4AddressEnabled; - log.info("Configured. Matching IPv4 Addresses is {}", - matchIpv4Address ? "enabled" : "disabled"); - } - boolean matchIpv4DscpEnabled = - isPropertyEnabled(properties, "matchIpv4Dscp"); - if (matchIpv4Dscp != matchIpv4DscpEnabled) { - matchIpv4Dscp = matchIpv4DscpEnabled; - log.info("Configured. Matching IPv4 DSCP and ECN is {}", - matchIpv4Dscp ? "enabled" : "disabled"); - } - boolean matchIpv6AddressEnabled = - isPropertyEnabled(properties, "matchIpv6Address"); - if (matchIpv6Address != matchIpv6AddressEnabled) { - matchIpv6Address = matchIpv6AddressEnabled; - log.info("Configured. Matching IPv6 Addresses is {}", - matchIpv6Address ? "enabled" : "disabled"); - } - boolean matchIpv6FlowLabelEnabled = - isPropertyEnabled(properties, "matchIpv6FlowLabel"); - if (matchIpv6FlowLabel != matchIpv6FlowLabelEnabled) { - matchIpv6FlowLabel = matchIpv6FlowLabelEnabled; - log.info("Configured. Matching IPv6 FlowLabel is {}", - matchIpv6FlowLabel ? "enabled" : "disabled"); - } - boolean matchTcpUdpPortsEnabled = - isPropertyEnabled(properties, "matchTcpUdpPorts"); - if (matchTcpUdpPorts != matchTcpUdpPortsEnabled) { - matchTcpUdpPorts = matchTcpUdpPortsEnabled; - log.info("Configured. Matching TCP/UDP fields is {}", - matchTcpUdpPorts ? "enabled" : "disabled"); - } - boolean matchIcmpFieldsEnabled = - isPropertyEnabled(properties, "matchIcmpFields"); - if (matchIcmpFields != matchIcmpFieldsEnabled) { - matchIcmpFields = matchIcmpFieldsEnabled; - log.info("Configured. Matching ICMP (v4 and v6) fields is {}", - matchIcmpFields ? "enabled" : "disabled"); - } - Integer flowTimeoutConfigured = - getIntegerProperty(properties, "flowTimeout"); - if (flowTimeoutConfigured == null) { - log.info("Flow Timeout is not configured, default value is {}", - flowTimeout); - } else { - flowTimeout = flowTimeoutConfigured; - log.info("Configured. Flow Timeout is configured to {}", - flowTimeout, " seconds"); - } - Integer flowPriorityConfigured = - getIntegerProperty(properties, "flowPriority"); - if (flowPriorityConfigured == null) { - log.info("Flow Priority is not configured, default value is {}", - flowPriority); - } else { - flowPriority = flowPriorityConfigured; - log.info("Configured. Flow Priority is configured to {}", - flowPriority); - } - - boolean ignoreIpv4McastPacketsEnabled = - isPropertyEnabled(properties, "ignoreIpv4McastPackets"); - if (ignoreIpv4McastPackets != ignoreIpv4McastPacketsEnabled) { - ignoreIpv4McastPackets = ignoreIpv4McastPacketsEnabled; - log.info("Configured. Ignore IPv4 multicast packets is {}", - ignoreIpv4McastPackets ? "enabled" : "disabled"); - } - } - - /** - * Get Integer property from the propertyName - * Return null if propertyName is not found. - * - * @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 Integer getIntegerProperty(Dictionary<?, ?> properties, - String propertyName) { - Integer value = null; - try { - String s = (String) properties.get(propertyName); - value = isNullOrEmpty(s) ? value : Integer.parseInt(s.trim()); - } catch (NumberFormatException | ClassCastException e) { - value = null; - } - return value; - } - - /** - * 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 true when the propertyName is defined and set to true - */ - private static boolean isPropertyEnabled(Dictionary<?, ?> properties, - String propertyName) { - boolean enabled = false; - try { - String flag = (String) properties.get(propertyName); - if (flag != null) { - enabled = flag.trim().equals("true"); - } - } catch (ClassCastException e) { - // No propertyName defined. - enabled = false; - } - return enabled; - } - - /** - * Packet processor responsible for forwarding packets along their paths. - */ - private class ReactivePacketProcessor 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; - } - - InboundPacket pkt = context.inPacket(); - Ethernet ethPkt = pkt.parsed(); - - if (ethPkt == null) { - return; - } - - // Bail if this is deemed to be a control packet. - if (isControlPacket(ethPkt)) { - return; - } - - // Skip IPv6 multicast packet when IPv6 forward is disabled. - if (!ipv6Forwarding && isIpv6Multicast(ethPkt)) { - return; - } - - HostId id = HostId.hostId(ethPkt.getDestinationMAC()); - - // Do not process link-local addresses in any way. - if (id.mac().isLinkLocal()) { - return; - } - - // Do not process IPv4 multicast packets, let mfwd handle them - if (ignoreIpv4McastPackets && ethPkt.getEtherType() == Ethernet.TYPE_IPV4) { - if (id.mac().isMulticast()) { - return; - } - } - - // Do we know who this is for? If not, flood and bail. - Host dst = hostService.getHost(id); - if (dst == null) { - flood(context); - return; - } - - // Are we on an edge switch that our destination is on? If so, - // simply forward out to the destination and bail. - if (pkt.receivedFrom().deviceId().equals(dst.location().deviceId())) { - if (!context.inPacket().receivedFrom().port().equals(dst.location().port())) { - installRule(context, dst.location().port()); - } - return; - } - - // Otherwise, get a set of paths that lead from here to the - // destination edge switch. - Set<Path> paths = - topologyService.getPaths(topologyService.currentTopology(), - pkt.receivedFrom().deviceId(), - dst.location().deviceId()); - if (paths.isEmpty()) { - // If there are no paths, flood and bail. - flood(context); - return; - } - - // Otherwise, pick a path that does not lead back to where we - // came from; if no such path, flood and bail. - Path path = pickForwardPathIfPossible(paths, pkt.receivedFrom().port()); - if (path == null) { - log.warn("Don't know where to go from here {} for {} -> {}", - pkt.receivedFrom(), ethPkt.getSourceMAC(), ethPkt.getDestinationMAC()); - flood(context); - return; - } - - // Otherwise forward and be done with it. - installRule(context, path.src().port()); - } - - } - - // Indicates whether this is a control packet, e.g. LLDP, BDDP - private boolean isControlPacket(Ethernet eth) { - short type = eth.getEtherType(); - return type == Ethernet.TYPE_LLDP || type == Ethernet.TYPE_BSN; - } - - // Indicated whether this is an IPv6 multicast packet. - private boolean isIpv6Multicast(Ethernet eth) { - return eth.getEtherType() == Ethernet.TYPE_IPV6 && eth.isMulticast(); - } - - // Selects a path from the given set that does not lead back to the - // specified port if possible. - private Path pickForwardPathIfPossible(Set<Path> paths, PortNumber notToPort) { - Path lastPath = null; - for (Path path : paths) { - lastPath = path; - if (!path.src().port().equals(notToPort)) { - return path; - } - } - return lastPath; - } - - // Floods the specified packet if permissible. - private void flood(PacketContext context) { - if (topologyService.isBroadcastPoint(topologyService.currentTopology(), - context.inPacket().receivedFrom())) { - packetOut(context, PortNumber.FLOOD); - } else { - context.block(); - } - } - - // Sends a packet out the specified port. - private void packetOut(PacketContext context, PortNumber portNumber) { - context.treatmentBuilder().setOutput(portNumber); - context.send(); - } - - // Install a rule forwarding the packet to the specified port. - private void installRule(PacketContext context, PortNumber portNumber) { - // - // We don't support (yet) buffer IDs in the Flow Service so - // packet out first. - // - Ethernet inPkt = context.inPacket().parsed(); - TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder(); - - // If PacketOutOnly or ARP packet than forward directly to output port - if (packetOutOnly || inPkt.getEtherType() == Ethernet.TYPE_ARP) { - packetOut(context, portNumber); - return; - } - - // - // If matchDstMacOnly - // Create flows matching dstMac only - // Else - // Create flows with default matching and include configured fields - // - if (matchDstMacOnly) { - selectorBuilder.matchEthDst(inPkt.getDestinationMAC()); - } else { - selectorBuilder.matchInPort(context.inPacket().receivedFrom().port()) - .matchEthSrc(inPkt.getSourceMAC()) - .matchEthDst(inPkt.getDestinationMAC()); - - // If configured Match Vlan ID - if (matchVlanId && inPkt.getVlanID() != Ethernet.VLAN_UNTAGGED) { - selectorBuilder.matchVlanId(VlanId.vlanId(inPkt.getVlanID())); - } - - // - // If configured and EtherType is IPv4 - Match IPv4 and - // TCP/UDP/ICMP fields - // - if (matchIpv4Address && inPkt.getEtherType() == Ethernet.TYPE_IPV4) { - IPv4 ipv4Packet = (IPv4) inPkt.getPayload(); - byte ipv4Protocol = ipv4Packet.getProtocol(); - Ip4Prefix matchIp4SrcPrefix = - Ip4Prefix.valueOf(ipv4Packet.getSourceAddress(), - Ip4Prefix.MAX_MASK_LENGTH); - Ip4Prefix matchIp4DstPrefix = - Ip4Prefix.valueOf(ipv4Packet.getDestinationAddress(), - Ip4Prefix.MAX_MASK_LENGTH); - selectorBuilder.matchEthType(Ethernet.TYPE_IPV4) - .matchIPSrc(matchIp4SrcPrefix) - .matchIPDst(matchIp4DstPrefix); - - if (matchIpv4Dscp) { - byte dscp = ipv4Packet.getDscp(); - byte ecn = ipv4Packet.getEcn(); - selectorBuilder.matchIPDscp(dscp).matchIPEcn(ecn); - } - - if (matchTcpUdpPorts && ipv4Protocol == IPv4.PROTOCOL_TCP) { - TCP tcpPacket = (TCP) ipv4Packet.getPayload(); - selectorBuilder.matchIPProtocol(ipv4Protocol) - .matchTcpSrc(TpPort.tpPort(tcpPacket.getSourcePort())) - .matchTcpDst(TpPort.tpPort(tcpPacket.getDestinationPort())); - } - if (matchTcpUdpPorts && ipv4Protocol == IPv4.PROTOCOL_UDP) { - UDP udpPacket = (UDP) ipv4Packet.getPayload(); - selectorBuilder.matchIPProtocol(ipv4Protocol) - .matchUdpSrc(TpPort.tpPort(udpPacket.getSourcePort())) - .matchUdpDst(TpPort.tpPort(udpPacket.getDestinationPort())); - } - if (matchIcmpFields && ipv4Protocol == IPv4.PROTOCOL_ICMP) { - ICMP icmpPacket = (ICMP) ipv4Packet.getPayload(); - selectorBuilder.matchIPProtocol(ipv4Protocol) - .matchIcmpType(icmpPacket.getIcmpType()) - .matchIcmpCode(icmpPacket.getIcmpCode()); - } - } - - // - // If configured and EtherType is IPv6 - Match IPv6 and - // TCP/UDP/ICMP fields - // - if (matchIpv6Address && inPkt.getEtherType() == Ethernet.TYPE_IPV6) { - IPv6 ipv6Packet = (IPv6) inPkt.getPayload(); - byte ipv6NextHeader = ipv6Packet.getNextHeader(); - Ip6Prefix matchIp6SrcPrefix = - Ip6Prefix.valueOf(ipv6Packet.getSourceAddress(), - Ip6Prefix.MAX_MASK_LENGTH); - Ip6Prefix matchIp6DstPrefix = - Ip6Prefix.valueOf(ipv6Packet.getDestinationAddress(), - Ip6Prefix.MAX_MASK_LENGTH); - selectorBuilder.matchEthType(Ethernet.TYPE_IPV6) - .matchIPv6Src(matchIp6SrcPrefix) - .matchIPv6Dst(matchIp6DstPrefix); - - if (matchIpv6FlowLabel) { - selectorBuilder.matchIPv6FlowLabel(ipv6Packet.getFlowLabel()); - } - - if (matchTcpUdpPorts && ipv6NextHeader == IPv6.PROTOCOL_TCP) { - TCP tcpPacket = (TCP) ipv6Packet.getPayload(); - selectorBuilder.matchIPProtocol(ipv6NextHeader) - .matchTcpSrc(TpPort.tpPort(tcpPacket.getSourcePort())) - .matchTcpDst(TpPort.tpPort(tcpPacket.getDestinationPort())); - } - if (matchTcpUdpPorts && ipv6NextHeader == IPv6.PROTOCOL_UDP) { - UDP udpPacket = (UDP) ipv6Packet.getPayload(); - selectorBuilder.matchIPProtocol(ipv6NextHeader) - .matchUdpSrc(TpPort.tpPort(udpPacket.getSourcePort())) - .matchUdpDst(TpPort.tpPort(udpPacket.getDestinationPort())); - } - if (matchIcmpFields && ipv6NextHeader == IPv6.PROTOCOL_ICMP6) { - ICMP6 icmp6Packet = (ICMP6) ipv6Packet.getPayload(); - selectorBuilder.matchIPProtocol(ipv6NextHeader) - .matchIcmpv6Type(icmp6Packet.getIcmpType()) - .matchIcmpv6Code(icmp6Packet.getIcmpCode()); - } - } - } - TrafficTreatment treatment = DefaultTrafficTreatment.builder() - .setOutput(portNumber) - .build(); - - ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder() - .withSelector(selectorBuilder.build()) - .withTreatment(treatment) - .withPriority(flowPriority) - .withFlag(ForwardingObjective.Flag.VERSATILE) - .fromApp(appId) - .makeTemporary(flowTimeout) - .add(); - - flowObjectiveService.forward(context.inPacket().receivedFrom().deviceId(), - forwardingObjective); - - // - // If packetOutOfppTable - // Send packet back to the OpenFlow pipeline to match installed flow - // Else - // Send packet direction on the appropriate port - // - if (packetOutOfppTable) { - packetOut(context, PortNumber.TABLE); - } else { - packetOut(context, portNumber); - } - } - - private class InternalTopologyListener implements TopologyListener { - @Override - public void event(TopologyEvent event) { - List<Event> reasons = event.reasons(); - if (reasons != null) { - reasons.forEach(re -> { - if (re instanceof LinkEvent) { - LinkEvent le = (LinkEvent) re; - if (le.type() == LinkEvent.Type.LINK_REMOVED) { - fixBlackhole(le.subject().src()); - } - } - }); - } - } - } - - private void fixBlackhole(ConnectPoint egress) { - Set<FlowEntry> rules = getFlowRulesFrom(egress); - Set<SrcDstPair> pairs = findSrcDstPairs(rules); - - Map<DeviceId, Set<Path>> srcPaths = new HashMap<>(); - - for (SrcDstPair sd : pairs) { - // get the edge deviceID for the src host - Host srcHost = hostService.getHost(HostId.hostId(sd.src)); - Host dstHost = hostService.getHost(HostId.hostId(sd.dst)); - if (srcHost != null && dstHost != null) { - DeviceId srcId = srcHost.location().deviceId(); - DeviceId dstId = dstHost.location().deviceId(); - log.trace("SRC ID is " + srcId + ", DST ID is " + dstId); - - cleanFlowRules(sd, egress.deviceId()); - - Set<Path> shortestPaths = srcPaths.get(srcId); - if (shortestPaths == null) { - shortestPaths = topologyService.getPaths(topologyService.currentTopology(), - egress.deviceId(), srcId); - srcPaths.put(srcId, shortestPaths); - } - backTrackBadNodes(shortestPaths, dstId, sd); - } - } - } - - // Backtracks from link down event to remove flows that lead to blackhole - private void backTrackBadNodes(Set<Path> shortestPaths, DeviceId dstId, SrcDstPair sd) { - for (Path p : shortestPaths) { - List<Link> pathLinks = p.links(); - for (int i = 0; i < pathLinks.size(); i = i + 1) { - Link curLink = pathLinks.get(i); - DeviceId curDevice = curLink.src().deviceId(); - - // skipping the first link because this link's src has already been pruned beforehand - if (i != 0) { - cleanFlowRules(sd, curDevice); - } - - Set<Path> pathsFromCurDevice = - topologyService.getPaths(topologyService.currentTopology(), - curDevice, dstId); - if (pickForwardPathIfPossible(pathsFromCurDevice, curLink.src().port()) != null) { - break; - } else { - if (i + 1 == pathLinks.size()) { - cleanFlowRules(sd, curLink.dst().deviceId()); - } - } - } - } - } - - // Removes flow rules off specified device with specific SrcDstPair - private void cleanFlowRules(SrcDstPair pair, DeviceId id) { - log.trace("Searching for flow rules to remove from: " + id); - log.trace("Removing flows w/ SRC=" + pair.src + ", DST=" + pair.dst); - for (FlowEntry r : flowRuleService.getFlowEntries(id)) { - boolean matchesSrc = false, matchesDst = false; - for (Instruction i : r.treatment().allInstructions()) { - if (i.type() == Instruction.Type.OUTPUT) { - // if the flow has matching src and dst - for (Criterion cr : r.selector().criteria()) { - if (cr.type() == Criterion.Type.ETH_DST) { - if (((EthCriterion) cr).mac().equals(pair.dst)) { - matchesDst = true; - } - } else if (cr.type() == Criterion.Type.ETH_SRC) { - if (((EthCriterion) cr).mac().equals(pair.src)) { - matchesSrc = true; - } - } - } - } - } - if (matchesDst && matchesSrc) { - log.trace("Removed flow rule from device: " + id); - flowRuleService.removeFlowRules((FlowRule) r); - } - } - - } - - // Returns a set of src/dst MAC pairs extracted from the specified set of flow entries - private Set<SrcDstPair> findSrcDstPairs(Set<FlowEntry> rules) { - ImmutableSet.Builder<SrcDstPair> builder = ImmutableSet.builder(); - for (FlowEntry r : rules) { - MacAddress src = null, dst = null; - for (Criterion cr : r.selector().criteria()) { - if (cr.type() == Criterion.Type.ETH_DST) { - dst = ((EthCriterion) cr).mac(); - } else if (cr.type() == Criterion.Type.ETH_SRC) { - src = ((EthCriterion) cr).mac(); - } - } - builder.add(new SrcDstPair(src, dst)); - } - return builder.build(); - } - - // Returns set of flow entries which were created by this application and - // which egress from the specified connection port - private Set<FlowEntry> getFlowRulesFrom(ConnectPoint egress) { - ImmutableSet.Builder<FlowEntry> builder = ImmutableSet.builder(); - flowRuleService.getFlowEntries(egress.deviceId()).forEach(r -> { - if (r.appId() == appId.id()) { - r.treatment().allInstructions().forEach(i -> { - if (i.type() == Instruction.Type.OUTPUT) { - if (((Instructions.OutputInstruction) i).port().equals(egress.port())) { - builder.add(r); - } - } - }); - } - }); - - return builder.build(); - } - - // Wrapper class for a source and destination pair of MAC addresses - private final class SrcDstPair { - final MacAddress src; - final MacAddress dst; - - private SrcDstPair(MacAddress src, MacAddress dst) { - this.src = src; - this.dst = dst; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SrcDstPair that = (SrcDstPair) o; - return Objects.equals(src, that.src) && - Objects.equals(dst, that.dst); - } - - @Override - public int hashCode() { - return Objects.hash(src, dst); - } - } -} diff --git a/framework/src/onos/apps/fwd/src/main/java/org/onosproject/fwd/package-info.java b/framework/src/onos/apps/fwd/src/main/java/org/onosproject/fwd/package-info.java deleted file mode 100644 index b947d40b..00000000 --- a/framework/src/onos/apps/fwd/src/main/java/org/onosproject/fwd/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ - -/** - * Sample application that provides simple form of reactive forwarding. - */ -package org.onosproject.fwd; |