aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java')
-rw-r--r--framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java444
1 files changed, 444 insertions, 0 deletions
diff --git a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
new file mode 100644
index 00000000..e050524a
--- /dev/null
+++ b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
@@ -0,0 +1,444 @@
+/*
+ * 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.provider.of.flow.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Optional;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.Ip6Prefix;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.IPDscpCriterion;
+import org.onosproject.net.flow.criteria.IPEcnCriterion;
+import org.onosproject.net.flow.criteria.IPProtocolCriterion;
+import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
+import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
+import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
+import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
+import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
+import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
+import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
+import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
+import org.onosproject.net.flow.criteria.MetadataCriterion;
+import org.onosproject.net.flow.criteria.MplsBosCriterion;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.OchSignalCriterion;
+import org.onosproject.net.flow.criteria.OchSignalTypeCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.SctpPortCriterion;
+import org.onosproject.net.flow.criteria.TcpPortCriterion;
+import org.onosproject.net.flow.criteria.TunnelIdCriterion;
+import org.onosproject.net.flow.criteria.UdpPortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.criteria.VlanPcpCriterion;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFFlowAdd;
+import org.projectfloodlight.openflow.protocol.OFFlowDelete;
+import org.projectfloodlight.openflow.protocol.OFFlowMod;
+import org.projectfloodlight.openflow.protocol.match.Match;
+import org.projectfloodlight.openflow.protocol.match.MatchField;
+import org.projectfloodlight.openflow.types.CircuitSignalID;
+import org.projectfloodlight.openflow.types.EthType;
+import org.projectfloodlight.openflow.types.ICMPv4Code;
+import org.projectfloodlight.openflow.types.ICMPv4Type;
+import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.IPv6Address;
+import org.projectfloodlight.openflow.types.IPv6FlowLabel;
+import org.projectfloodlight.openflow.types.IpDscp;
+import org.projectfloodlight.openflow.types.IpEcn;
+import org.projectfloodlight.openflow.types.IpProtocol;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.Masked;
+import org.projectfloodlight.openflow.types.OFBooleanValue;
+import org.projectfloodlight.openflow.types.OFMetadata;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.OFVlanVidMatch;
+import org.projectfloodlight.openflow.types.TransportPort;
+import org.projectfloodlight.openflow.types.U16;
+import org.projectfloodlight.openflow.types.U32;
+import org.projectfloodlight.openflow.types.U64;
+import org.projectfloodlight.openflow.types.U8;
+import org.projectfloodlight.openflow.types.VlanPcp;
+import org.projectfloodlight.openflow.types.VlanVid;
+import org.slf4j.Logger;
+
+/**
+ * Builder for OpenFlow flow mods based on FlowRules.
+ */
+public abstract class FlowModBuilder {
+
+ private final Logger log = getLogger(getClass());
+
+ private final OFFactory factory;
+ private final FlowRule flowRule;
+ private final TrafficSelector selector;
+ protected final Long xid;
+
+ /**
+ * Creates a new flow mod builder.
+ *
+ * @param flowRule the flow rule to transform into a flow mod
+ * @param factory the OpenFlow factory to use to build the flow mod
+ * @param xid the transaction ID
+ * @return the new flow mod builder
+ */
+ public static FlowModBuilder builder(FlowRule flowRule,
+ OFFactory factory,
+ Optional<Long> xid) {
+ switch (factory.getVersion()) {
+ case OF_10:
+ return new FlowModBuilderVer10(flowRule, factory, xid);
+ case OF_13:
+ return new FlowModBuilderVer13(flowRule, factory, xid);
+ default:
+ throw new UnsupportedOperationException(
+ "No flow mod builder for protocol version " + factory.getVersion());
+ }
+ }
+
+ /**
+ * Constructs a flow mod builder.
+ *
+ * @param flowRule the flow rule to transform into a flow mod
+ * @param factory the OpenFlow factory to use to build the flow mod
+ * @param xid the transaction ID
+ */
+ protected FlowModBuilder(FlowRule flowRule, OFFactory factory, Optional<Long> xid) {
+ this.factory = factory;
+ this.flowRule = flowRule;
+ this.selector = flowRule.selector();
+ this.xid = xid.orElse(0L);
+
+ }
+
+ /**
+ * Builds an ADD flow mod.
+ *
+ * @return the flow mod
+ */
+ public abstract OFFlowAdd buildFlowAdd();
+
+ /**
+ * Builds a MODIFY flow mod.
+ *
+ * @return the flow mod
+ */
+ public abstract OFFlowMod buildFlowMod();
+
+ /**
+ * Builds a DELETE flow mod.
+ *
+ * @return the flow mod
+ */
+ public abstract OFFlowDelete buildFlowDel();
+
+ /**
+ * Builds the match for the flow mod.
+ *
+ * @return the match
+ */
+ // CHECKSTYLE IGNORE MethodLength FOR NEXT 300 LINES
+ protected Match buildMatch() {
+ Match.Builder mBuilder = factory.buildMatch();
+ Ip6Address ip6Address;
+ Ip4Prefix ip4Prefix;
+ Ip6Prefix ip6Prefix;
+ EthCriterion ethCriterion;
+ IPCriterion ipCriterion;
+ TcpPortCriterion tcpPortCriterion;
+ UdpPortCriterion udpPortCriterion;
+ SctpPortCriterion sctpPortCriterion;
+ IPv6NDLinkLayerAddressCriterion llAddressCriterion;
+
+ for (Criterion c : selector.criteria()) {
+ switch (c.type()) {
+ case IN_PORT:
+ PortCriterion inPort = (PortCriterion) c;
+ mBuilder.setExact(MatchField.IN_PORT,
+ OFPort.of((int) inPort.port().toLong()));
+ break;
+ case IN_PHY_PORT:
+ PortCriterion inPhyPort = (PortCriterion) c;
+ mBuilder.setExact(MatchField.IN_PORT,
+ OFPort.of((int) inPhyPort.port().toLong()));
+ break;
+ case METADATA:
+ MetadataCriterion metadata = (MetadataCriterion) c;
+ mBuilder.setExact(MatchField.METADATA,
+ OFMetadata.ofRaw(metadata.metadata()));
+ break;
+ case ETH_DST:
+ ethCriterion = (EthCriterion) c;
+ mBuilder.setExact(MatchField.ETH_DST,
+ MacAddress.of(ethCriterion.mac().toLong()));
+ break;
+ case ETH_SRC:
+ ethCriterion = (EthCriterion) c;
+ mBuilder.setExact(MatchField.ETH_SRC,
+ MacAddress.of(ethCriterion.mac().toLong()));
+ break;
+ case ETH_TYPE:
+ EthTypeCriterion ethType = (EthTypeCriterion) c;
+ mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType().toShort()));
+ break;
+ case VLAN_VID:
+ VlanIdCriterion vid = (VlanIdCriterion) c;
+
+ if (vid.vlanId().equals(VlanId.ANY)) {
+ mBuilder.setMasked(MatchField.VLAN_VID, OFVlanVidMatch.PRESENT,
+ OFVlanVidMatch.PRESENT);
+ } else if (vid.vlanId().equals(VlanId.NONE)) {
+ mBuilder.setExact(MatchField.VLAN_VID, OFVlanVidMatch.NONE);
+ } else {
+ mBuilder.setExact(MatchField.VLAN_VID,
+ OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
+ }
+ break;
+ case VLAN_PCP:
+ VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
+ mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
+ break;
+ case IP_DSCP:
+ IPDscpCriterion ipDscpCriterion = (IPDscpCriterion) c;
+ mBuilder.setExact(MatchField.IP_DSCP,
+ IpDscp.of(ipDscpCriterion.ipDscp()));
+ break;
+ case IP_ECN:
+ IPEcnCriterion ipEcnCriterion = (IPEcnCriterion) c;
+ mBuilder.setExact(MatchField.IP_ECN,
+ IpEcn.of(ipEcnCriterion.ipEcn()));
+ break;
+ case IP_PROTO:
+ IPProtocolCriterion p = (IPProtocolCriterion) c;
+ mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
+ break;
+ case IPV4_SRC:
+ ipCriterion = (IPCriterion) c;
+ ip4Prefix = ipCriterion.ip().getIp4Prefix();
+ if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
+ Ip4Address maskAddr =
+ Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
+ Masked<IPv4Address> maskedIp =
+ Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
+ IPv4Address.of(maskAddr.toInt()));
+ mBuilder.setMasked(MatchField.IPV4_SRC, maskedIp);
+ } else {
+ mBuilder.setExact(MatchField.IPV4_SRC,
+ IPv4Address.of(ip4Prefix.address().toInt()));
+ }
+ break;
+ case IPV4_DST:
+ ipCriterion = (IPCriterion) c;
+ ip4Prefix = ipCriterion.ip().getIp4Prefix();
+ if (ip4Prefix.prefixLength() != Ip4Prefix.MAX_MASK_LENGTH) {
+ Ip4Address maskAddr =
+ Ip4Address.makeMaskPrefix(ip4Prefix.prefixLength());
+ Masked<IPv4Address> maskedIp =
+ Masked.of(IPv4Address.of(ip4Prefix.address().toInt()),
+ IPv4Address.of(maskAddr.toInt()));
+ mBuilder.setMasked(MatchField.IPV4_DST, maskedIp);
+ } else {
+ mBuilder.setExact(MatchField.IPV4_DST,
+ IPv4Address.of(ip4Prefix.address().toInt()));
+ }
+ break;
+ case TCP_SRC:
+ tcpPortCriterion = (TcpPortCriterion) c;
+ mBuilder.setExact(MatchField.TCP_SRC,
+ TransportPort.of(tcpPortCriterion.tcpPort().toInt()));
+ break;
+ case TCP_DST:
+ tcpPortCriterion = (TcpPortCriterion) c;
+ mBuilder.setExact(MatchField.TCP_DST,
+ TransportPort.of(tcpPortCriterion.tcpPort().toInt()));
+ break;
+ case UDP_SRC:
+ udpPortCriterion = (UdpPortCriterion) c;
+ mBuilder.setExact(MatchField.UDP_SRC,
+ TransportPort.of(udpPortCriterion.udpPort().toInt()));
+ break;
+ case UDP_DST:
+ udpPortCriterion = (UdpPortCriterion) c;
+ mBuilder.setExact(MatchField.UDP_DST,
+ TransportPort.of(udpPortCriterion.udpPort().toInt()));
+ break;
+ case SCTP_SRC:
+ sctpPortCriterion = (SctpPortCriterion) c;
+ mBuilder.setExact(MatchField.SCTP_SRC,
+ TransportPort.of(sctpPortCriterion.sctpPort().toInt()));
+ break;
+ case SCTP_DST:
+ sctpPortCriterion = (SctpPortCriterion) c;
+ mBuilder.setExact(MatchField.SCTP_DST,
+ TransportPort.of(sctpPortCriterion.sctpPort().toInt()));
+ break;
+ case ICMPV4_TYPE:
+ IcmpTypeCriterion icmpType = (IcmpTypeCriterion) c;
+ mBuilder.setExact(MatchField.ICMPV4_TYPE,
+ ICMPv4Type.of(icmpType.icmpType()));
+ break;
+ case ICMPV4_CODE:
+ IcmpCodeCriterion icmpCode = (IcmpCodeCriterion) c;
+ mBuilder.setExact(MatchField.ICMPV4_CODE,
+ ICMPv4Code.of(icmpCode.icmpCode()));
+ break;
+ case IPV6_SRC:
+ ipCriterion = (IPCriterion) c;
+ ip6Prefix = ipCriterion.ip().getIp6Prefix();
+ if (ip6Prefix.prefixLength() != Ip6Prefix.MAX_MASK_LENGTH) {
+ Ip6Address maskAddr =
+ Ip6Address.makeMaskPrefix(ip6Prefix.prefixLength());
+ Masked<IPv6Address> maskedIp =
+ Masked.of(IPv6Address.of(ip6Prefix.address().toString()),
+ IPv6Address.of(maskAddr.toString()));
+ mBuilder.setMasked(MatchField.IPV6_SRC, maskedIp);
+ } else {
+ mBuilder.setExact(MatchField.IPV6_SRC,
+ IPv6Address.of(ip6Prefix.address().toString()));
+ }
+ break;
+ case IPV6_DST:
+ ipCriterion = (IPCriterion) c;
+ ip6Prefix = ipCriterion.ip().getIp6Prefix();
+ if (ip6Prefix.prefixLength() != Ip6Prefix.MAX_MASK_LENGTH) {
+ Ip6Address maskAddr =
+ Ip6Address.makeMaskPrefix(ip6Prefix.prefixLength());
+ Masked<IPv6Address> maskedIp =
+ Masked.of(IPv6Address.of(ip6Prefix.address().toString()),
+ IPv6Address.of(maskAddr.toString()));
+ mBuilder.setMasked(MatchField.IPV6_DST, maskedIp);
+ } else {
+ mBuilder.setExact(MatchField.IPV6_DST,
+ IPv6Address.of(ip6Prefix.address().toString()));
+ }
+ break;
+ case IPV6_FLABEL:
+ IPv6FlowLabelCriterion flowLabelCriterion =
+ (IPv6FlowLabelCriterion) c;
+ mBuilder.setExact(MatchField.IPV6_FLABEL,
+ IPv6FlowLabel.of(flowLabelCriterion.flowLabel()));
+ break;
+ case ICMPV6_TYPE:
+ Icmpv6TypeCriterion icmpv6Type = (Icmpv6TypeCriterion) c;
+ mBuilder.setExact(MatchField.ICMPV6_TYPE,
+ U8.of(icmpv6Type.icmpv6Type()));
+ break;
+ case ICMPV6_CODE:
+ Icmpv6CodeCriterion icmpv6Code = (Icmpv6CodeCriterion) c;
+ mBuilder.setExact(MatchField.ICMPV6_CODE,
+ U8.of(icmpv6Code.icmpv6Code()));
+ break;
+ case IPV6_ND_TARGET:
+ IPv6NDTargetAddressCriterion targetAddressCriterion =
+ (IPv6NDTargetAddressCriterion) c;
+ ip6Address = targetAddressCriterion.targetAddress();
+ mBuilder.setExact(MatchField.IPV6_ND_TARGET,
+ IPv6Address.of(ip6Address.toOctets()));
+ break;
+ case IPV6_ND_SLL:
+ llAddressCriterion =
+ (IPv6NDLinkLayerAddressCriterion) c;
+ mBuilder.setExact(MatchField.IPV6_ND_SLL,
+ MacAddress.of(llAddressCriterion.mac().toLong()));
+ break;
+ case IPV6_ND_TLL:
+ llAddressCriterion =
+ (IPv6NDLinkLayerAddressCriterion) c;
+ mBuilder.setExact(MatchField.IPV6_ND_TLL,
+ MacAddress.of(llAddressCriterion.mac().toLong()));
+ break;
+ case MPLS_LABEL:
+ MplsCriterion mp = (MplsCriterion) c;
+ mBuilder.setExact(MatchField.MPLS_LABEL, U32.of(mp.label().toInt()));
+ break;
+ case IPV6_EXTHDR:
+ IPv6ExthdrFlagsCriterion exthdrFlagsCriterion =
+ (IPv6ExthdrFlagsCriterion) c;
+ mBuilder.setExact(MatchField.IPV6_EXTHDR,
+ U16.of(exthdrFlagsCriterion.exthdrFlags()));
+ break;
+ case OCH_SIGID:
+ try {
+ OchSignalCriterion ochSignalCriterion = (OchSignalCriterion) c;
+ OchSignal signal = ochSignalCriterion.lambda();
+ byte gridType = OpenFlowValueMapper.lookupGridType(signal.gridType());
+ byte channelSpacing = OpenFlowValueMapper.lookupChannelSpacing(signal.channelSpacing());
+ mBuilder.setExact(MatchField.OCH_SIGID,
+ new CircuitSignalID(gridType, channelSpacing,
+ (short) signal.spacingMultiplier(), (short) signal.slotGranularity()));
+ } catch (NoMappingFoundException e) {
+ log.warn(e.getMessage());
+ }
+ break;
+ case OCH_SIGTYPE:
+ OchSignalTypeCriterion sc = (OchSignalTypeCriterion) c;
+ byte signalType = OpenFlowValueMapper.lookupOchSignalType(sc.signalType());
+ mBuilder.setExact(MatchField.OCH_SIGTYPE, U8.of(signalType));
+ break;
+ case TUNNEL_ID:
+ TunnelIdCriterion tunnelId = (TunnelIdCriterion) c;
+ mBuilder.setExact(MatchField.TUNNEL_ID,
+ U64.of(tunnelId.tunnelId()));
+ break;
+ case MPLS_BOS:
+ MplsBosCriterion mplsBos = (MplsBosCriterion) c;
+ mBuilder.setExact(MatchField.MPLS_BOS,
+ mplsBos.mplsBos() ? OFBooleanValue.TRUE
+ : OFBooleanValue.FALSE);
+ break;
+ case ARP_OP:
+ case ARP_SHA:
+ case ARP_SPA:
+ case ARP_THA:
+ case ARP_TPA:
+ case MPLS_TC:
+ case PBB_ISID:
+ default:
+ log.warn("Match type {} not yet implemented.", c.type());
+ }
+ }
+ return mBuilder.build();
+ }
+
+ /**
+ * Returns the flow rule for this builder.
+ *
+ * @return the flow rule
+ */
+ protected FlowRule flowRule() {
+ return flowRule;
+ }
+
+ /**
+ * Returns the factory used for building OpenFlow constructs.
+ *
+ * @return the factory
+ */
+ protected OFFactory factory() {
+ return factory;
+ }
+
+}