From c8bd97c5e108207c890c8a0b437f85dac149ba65 Mon Sep 17 00:00:00 2001 From: Hyunsun Moon Date: Sat, 18 Jul 2015 22:47:33 -0700 Subject: [PATCH] ONOS-2403 Support setting TCP/UDP port action in flow rule for OpenFlow13 Change-Id: I4ce84aba9db03a66ebcfb34959c11cc4acadb07b --- .../net/flow/DefaultTrafficTreatment.java | 21 +++++++++ .../net/flow/TrafficTreatment.java | 32 +++++++++++++ .../net/flow/instructions/Instructions.java | 46 +++++++++++++++++++ .../L4ModificationInstruction.java | 8 ++-- .../store/serializers/KryoNamespaces.java | 4 ++ .../of/flow/impl/FlowEntryBuilder.java | 25 ++++++++-- .../of/flow/impl/FlowModBuilderVer13.java | 40 +++++++++++++++- 7 files changed, 167 insertions(+), 9 deletions(-) diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java index fe657e6c8c..06c49baf89 100644 --- a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java +++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java @@ -224,6 +224,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { case L0MODIFICATION: case L2MODIFICATION: case L3MODIFICATION: + case L4MODIFICATION: current.add(instruction); break; case TABLE: @@ -389,6 +390,26 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { return add(Instructions.modTunnelId(tunnelId)); } + @Override + public TrafficTreatment.Builder setTcpSrc(short port) { + return add(Instructions.modTcpSrc(port)); + } + + @Override + public TrafficTreatment.Builder setTcpDst(short port) { + return add(Instructions.modTcpDst(port)); + } + + @Override + public TrafficTreatment.Builder setUdpSrc(short port) { + return add(Instructions.modUdpSrc(port)); + } + + @Override + public TrafficTreatment.Builder setUdpDst(short port) { + return add(Instructions.modUdpDst(port)); + } + @Override public TrafficTreatment build() { //Don't add DROP instruction by default when instruction diff --git a/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java index 35ef6d3440..d125a9f3c6 100644 --- a/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java +++ b/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java @@ -318,6 +318,38 @@ public interface TrafficTreatment { */ Builder setTunnelId(long tunnelId); + /** + * Sets the src TCP port. + * + * @param port a port number + * @return a treatment builder + */ + Builder setTcpSrc(short port); + + /** + * Sets the dst TCP port. + * + * @param port a port number + * @return a treatment builder + */ + Builder setTcpDst(short port); + + /** + * Sets the src UDP port. + * + * @param port a port number + * @return a treatment builder + */ + Builder setUdpSrc(short port); + + /** + * Sets the dst UDP port. + * + * @param port a port number + * @return a treatment builder + */ + Builder setUdpDst(short port); + /** * Builds an immutable traffic treatment descriptor. *

diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java index 0467a91774..3cacfa5988 100644 --- a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java +++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java @@ -32,6 +32,8 @@ import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction; import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction; +import org.onosproject.net.flow.instructions.L4ModificationInstruction.L4SubType; +import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction; import java.util.Objects; @@ -360,6 +362,50 @@ public final class Instructions { return new L2ModificationInstruction.ModTunnelIdInstruction(tunnelId); } + /** + * Creates a TCP src modification. + * + * @param port the TCP port number to modify to + * @return a L4 modification + */ + public static L4ModificationInstruction modTcpSrc(short port) { + checkNotNull(port, "Src TCP port cannot be null"); + return new ModTransportPortInstruction(L4SubType.TCP_SRC, port); + } + + /** + * Creates a TCP dst modification. + * + * @param port the TCP port number to modify to + * @return a L4 modification + */ + public static L4ModificationInstruction modTcpDst(short port) { + checkNotNull(port, "Dst TCP port cannot be null"); + return new ModTransportPortInstruction(L4SubType.TCP_DST, port); + } + + /** + * Creates a UDP src modification. + * + * @param port the UDP port number to modify to + * @return a L4 modification + */ + public static L4ModificationInstruction modUdpSrc(short port) { + checkNotNull(port, "Src UDP port cannot be null"); + return new ModTransportPortInstruction(L4SubType.UDP_SRC, port); + } + + /** + * Creates a UDP dst modification. + * + * @param port the UDP port number to modify to + * @return a L4 modification + */ + public static L4ModificationInstruction modUdpDst(short port) { + checkNotNull(port, "Dst UDP port cannot be null"); + return new ModTransportPortInstruction(L4SubType.UDP_DST, port); + } + /** * Drop instruction. */ diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/L4ModificationInstruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/L4ModificationInstruction.java index 09f02fbe3c..c78f639cbe 100644 --- a/core/api/src/main/java/org/onosproject/net/flow/instructions/L4ModificationInstruction.java +++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/L4ModificationInstruction.java @@ -66,12 +66,12 @@ public abstract class L4ModificationInstruction implements Instruction { /** * Represents a L4 src/dst modification instruction. */ - public static final class ModL4PortInstruction extends L4ModificationInstruction { + public static final class ModTransportPortInstruction extends L4ModificationInstruction { private final L4SubType subtype; private final short port; - public ModL4PortInstruction(L4SubType subtype, short port) { + public ModTransportPortInstruction(L4SubType subtype, short port) { this.subtype = subtype; this.port = port; } @@ -101,8 +101,8 @@ public abstract class L4ModificationInstruction implements Instruction { if (this == obj) { return true; } - if (obj instanceof ModL4PortInstruction) { - ModL4PortInstruction that = (ModL4PortInstruction) obj; + if (obj instanceof ModTransportPortInstruction) { + ModTransportPortInstruction that = (ModTransportPortInstruction) obj; return Objects.equals(port, that.port) && Objects.equals(this.subtype(), that.subtype()); } diff --git a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java index b68e1d616d..2f3440826f 100644 --- a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java +++ b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java @@ -127,6 +127,7 @@ import org.onosproject.net.flow.instructions.Instructions; import org.onosproject.net.flow.instructions.L0ModificationInstruction; import org.onosproject.net.flow.instructions.L2ModificationInstruction; import org.onosproject.net.flow.instructions.L3ModificationInstruction; +import org.onosproject.net.flow.instructions.L4ModificationInstruction; import org.onosproject.net.host.DefaultHostDescription; import org.onosproject.net.host.HostDescription; import org.onosproject.net.intent.ConnectivityIntent; @@ -354,6 +355,9 @@ public final class KryoNamespaces { L3ModificationInstruction.ModIPInstruction.class, L3ModificationInstruction.ModIPv6FlowLabelInstruction.class, L3ModificationInstruction.ModTtlInstruction.class, + L4ModificationInstruction.class, + L4ModificationInstruction.L4SubType.class, + L4ModificationInstruction.ModTransportPortInstruction.class, RoleInfo.class, FlowRuleBatchEvent.class, FlowRuleBatchEvent.Type.class, diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java index 676046236b..4a3872c5b3 100644 --- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java +++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java @@ -71,6 +71,7 @@ import org.projectfloodlight.openflow.types.IPv4Address; import org.projectfloodlight.openflow.types.IPv6Address; import org.projectfloodlight.openflow.types.Masked; import org.projectfloodlight.openflow.types.OFVlanVidMatch; +import org.projectfloodlight.openflow.types.TransportPort; import org.projectfloodlight.openflow.types.U32; import org.projectfloodlight.openflow.types.U64; import org.projectfloodlight.openflow.types.U8; @@ -408,6 +409,26 @@ public class FlowEntryBuilder { OFOxm tunnelId = (OFOxm) oxm; builder.setTunnelId(tunnelId.getValue().getValue()); break; + case TCP_DST: + @SuppressWarnings("unchecked") + OFOxm tcpdst = (OFOxm) oxm; + builder.setTcpDst((short) tcpdst.getValue().getPort()); + break; + case TCP_SRC: + @SuppressWarnings("unchecked") + OFOxm tcpsrc = (OFOxm) oxm; + builder.setTcpSrc((short) tcpsrc.getValue().getPort()); + break; + case UDP_DST: + @SuppressWarnings("unchecked") + OFOxm udpdst = (OFOxm) oxm; + builder.setUdpDst((short) udpdst.getValue().getPort()); + break; + case UDP_SRC: + @SuppressWarnings("unchecked") + OFOxm udpsrc = (OFOxm) oxm; + builder.setUdpSrc((short) udpsrc.getValue().getPort()); + break; case ARP_OP: case ARP_SHA: case ARP_SPA: @@ -455,10 +476,6 @@ public class FlowEntryBuilder { case OCH_SIGTYPE_BASIC: case SCTP_DST: case SCTP_SRC: - case TCP_DST: - case TCP_SRC: - case UDP_DST: - case UDP_SRC: default: log.warn("Set field type {} not yet implemented.", oxm.getMatchField().id); break; diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java index 7bbc3759c8..58c19ad691 100644 --- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java +++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java @@ -39,6 +39,8 @@ import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnel import org.onosproject.net.flow.instructions.L3ModificationInstruction; import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction; +import org.onosproject.net.flow.instructions.L4ModificationInstruction; +import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction; import org.projectfloodlight.openflow.protocol.OFFactory; import org.projectfloodlight.openflow.protocol.OFFlowAdd; import org.projectfloodlight.openflow.protocol.OFFlowDelete; @@ -61,6 +63,7 @@ import org.projectfloodlight.openflow.types.OFGroup; import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.OFVlanVidMatch; import org.projectfloodlight.openflow.types.TableId; +import org.projectfloodlight.openflow.types.TransportPort; import org.projectfloodlight.openflow.types.U32; import org.projectfloodlight.openflow.types.U64; import org.projectfloodlight.openflow.types.VlanPcp; @@ -214,6 +217,9 @@ public class FlowModBuilderVer13 extends FlowModBuilder { case L3MODIFICATION: actions.add(buildL3Modification(i)); break; + case L4MODIFICATION: + actions.add(buildL4Modification(i)); + break; case OUTPUT: OutputInstruction out = (OutputInstruction) i; OFActionOutput.Builder action = factory().actions().buildOutput() @@ -327,7 +333,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ModMplsLabelInstruction mplsLabel = (ModMplsLabelInstruction) l2m; oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label() - .longValue())); + .longValue())); break; case DEC_MPLS_TTL: return factory().actions().decMplsTtl(); @@ -402,4 +408,36 @@ public class FlowModBuilderVer13 extends FlowModBuilder { return null; } + private OFAction buildL4Modification(Instruction i) { + L4ModificationInstruction l4m = (L4ModificationInstruction) i; + ModTransportPortInstruction tp; + OFOxm oxm = null; + switch (l4m.subtype()) { + case TCP_SRC: + tp = (ModTransportPortInstruction) l4m; + oxm = factory().oxms().tcpSrc(TransportPort.of(tp.port())); + break; + case TCP_DST: + tp = (ModTransportPortInstruction) l4m; + oxm = factory().oxms().tcpDst(TransportPort.of(tp.port())); + break; + case UDP_SRC: + tp = (ModTransportPortInstruction) l4m; + oxm = factory().oxms().udpSrc(TransportPort.of(tp.port())); + break; + case UDP_DST: + tp = (ModTransportPortInstruction) l4m; + oxm = factory().oxms().udpDst(TransportPort.of(tp.port())); + break; + default: + log.warn("Unimplemented action type {}.", l4m.subtype()); + break; + } + + if (oxm != null) { + return factory().actions().buildSetField().setField(oxm).build(); + } + return null; + } + }