blob: 3e2335b59098fb5bb63f5ae037c7d751b0bbc6fc [file] [log] [blame]
Thomas Vachuska83e090e2014-10-22 14:25:35 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska83e090e2014-10-22 14:25:35 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska83e090e2014-10-22 14:25:35 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska83e090e2014-10-22 14:25:35 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.flow.instructions;
alshabib55a55d92014-09-16 11:59:31 -070017
Steffen Gebertba2d3b72015-10-22 11:14:31 +020018import com.google.common.base.MoreObjects;
alshabib7b808c52015-06-26 14:22:24 -070019import org.onlab.packet.EthType;
Jonathan Hart54b406b2015-03-06 16:24:14 -080020import org.onlab.packet.IpAddress;
21import org.onlab.packet.MacAddress;
22import org.onlab.packet.MplsLabel;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -070023import org.onlab.packet.TpPort;
Jonathan Hart54b406b2015-03-06 16:24:14 -080024import org.onlab.packet.VlanId;
sangho8995ac52015-02-04 11:29:03 -080025import org.onosproject.core.GroupId;
Jonathan Hart3c259162015-10-21 21:31:19 -070026import org.onosproject.net.DeviceId;
Sho SHIMIZU2e7ac842015-05-05 15:45:38 -070027import org.onosproject.net.IndexedLambda;
28import org.onosproject.net.Lambda;
Sho SHIMIZUe9e12752015-05-05 14:45:40 -070029import org.onosproject.net.OchSignal;
Yafit Hadar52d81552015-10-07 12:26:52 +030030import org.onosproject.net.OduSignalId;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.net.PortNumber;
32import org.onosproject.net.flow.instructions.L0ModificationInstruction.L0SubType;
33import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
Sho SHIMIZU2e7ac842015-05-05 15:45:38 -070034import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction;
Yafit Hadar52d81552015-10-07 12:26:52 +030035import org.onosproject.net.flow.instructions.L1ModificationInstruction.ModOduSignalIdInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080036import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType;
37import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
lishuai3cce60b2015-12-01 19:35:16 +080038import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
39import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
40import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080041import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
sangho3f97a17d2015-01-29 22:56:29 -080042import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction;
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -070043import org.onosproject.net.flow.instructions.L4ModificationInstruction.L4SubType;
44import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
alshabib10c810b2015-08-18 16:59:04 -070045import org.onosproject.net.meter.MeterId;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080046
Jonathan Hart54b406b2015-03-06 16:24:14 -080047import java.util.Objects;
48
49import static com.google.common.base.MoreObjects.toStringHelper;
50import static com.google.common.base.Preconditions.checkNotNull;
alshabib64231f62014-09-16 17:58:36 -070051
alshabib55a55d92014-09-16 11:59:31 -070052/**
53 * Factory class for creating various traffic treatment instructions.
54 */
55public final class Instructions {
56
Jonathan Hartc7840bd2016-01-21 23:26:29 -080057 private static final String SEPARATOR = ":";
58
alshabib55a55d92014-09-16 11:59:31 -070059 // Ban construction
60 private Instructions() {}
61
62 /**
63 * Creates an output instruction using the specified port number. This can
64 * include logical ports such as CONTROLLER, FLOOD, etc.
65 *
66 * @param number port number
67 * @return output instruction
68 */
69 public static OutputInstruction createOutput(final PortNumber number) {
70 checkNotNull(number, "PortNumber cannot be null");
71 return new OutputInstruction(number);
72 }
73
74 /**
Charles Chan7efabeb2015-09-28 15:12:19 -070075 * Creates a no action instruction.
76 *
77 * @return no action instruction
78 */
79 public static NoActionInstruction createNoAction() {
80 return new NoActionInstruction();
81 }
82
83 /**
sangho8995ac52015-02-04 11:29:03 -080084 * Creates a group instruction.
85 *
86 * @param groupId Group Id
87 * @return group instruction
88 */
89 public static GroupInstruction createGroup(final GroupId groupId) {
90 checkNotNull(groupId, "GroupId cannot be null");
91 return new GroupInstruction(groupId);
92 }
93
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +020094 /**
95 * Creates a set-queue instruction.
96 *
97 * @param queueId Queue Id
Steffen Gebertba2d3b72015-10-22 11:14:31 +020098 * @param port Port number
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +020099 * @return set-queue instruction
100 */
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200101 public static SetQueueInstruction setQueue(final long queueId, final PortNumber port) {
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200102 checkNotNull(queueId, "queue ID cannot be null");
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200103 return new SetQueueInstruction(queueId, port);
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200104 }
105
Jian Li1ef82db2016-03-03 14:43:21 -0800106 /**
107 * Creates a meter instruction.
108 *
109 * @param meterId Meter Id
110 * @return meter instruction
111 */
alshabib10c810b2015-08-18 16:59:04 -0700112 public static MeterInstruction meterTraffic(final MeterId meterId) {
113 checkNotNull(meterId, "meter id cannot be null");
114 return new MeterInstruction(meterId);
115 }
116
sangho8995ac52015-02-04 11:29:03 -0800117 /**
Sho SHIMIZUe9e12752015-05-05 14:45:40 -0700118 * Creates an L0 modification with the specified OCh signal.
119 *
120 * @param lambda OCh signal
121 * @return an L0 modification
122 */
Sho SHIMIZU2e7ac842015-05-05 15:45:38 -0700123 public static L0ModificationInstruction modL0Lambda(Lambda lambda) {
Sho SHIMIZUe9e12752015-05-05 14:45:40 -0700124 checkNotNull(lambda, "L0 OCh signal cannot be null");
Sho SHIMIZU2e7ac842015-05-05 15:45:38 -0700125
126 if (lambda instanceof IndexedLambda) {
127 return new ModLambdaInstruction(L0SubType.LAMBDA, (short) ((IndexedLambda) lambda).index());
128 } else if (lambda instanceof OchSignal) {
129 return new ModOchSignalInstruction((OchSignal) lambda);
130 } else {
131 throw new UnsupportedOperationException(String.format("Unsupported type: %s", lambda));
132 }
Sho SHIMIZUe9e12752015-05-05 14:45:40 -0700133 }
134
135 /**
Yafit Hadar52d81552015-10-07 12:26:52 +0300136 * Creates an L1 modification with the specified ODU signal Id.
137 *
138 * @param oduSignalId ODU Signal Id
139 * @return a L1 modification
140 */
141 public static L1ModificationInstruction modL1OduSignalId(OduSignalId oduSignalId) {
142 checkNotNull(oduSignalId, "L1 ODU signal ID cannot be null");
143 return new ModOduSignalIdInstruction(oduSignalId);
144 }
145 /**
alshabib55a55d92014-09-16 11:59:31 -0700146 * Creates a l2 src modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800147 *
148 * @param addr the mac address to modify to
alshabib55a55d92014-09-16 11:59:31 -0700149 * @return a l2 modification
150 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700151 public static L2ModificationInstruction modL2Src(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -0700152 checkNotNull(addr, "Src l2 address cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700153 return new L2ModificationInstruction.ModEtherInstruction(
154 L2ModificationInstruction.L2SubType.ETH_SRC, addr);
alshabib55a55d92014-09-16 11:59:31 -0700155 }
156
157 /**
158 * Creates a L2 dst modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800159 *
160 * @param addr the mac address to modify to
alshabib55a55d92014-09-16 11:59:31 -0700161 * @return a L2 modification
162 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700163 public static L2ModificationInstruction modL2Dst(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -0700164 checkNotNull(addr, "Dst l2 address cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700165 return new L2ModificationInstruction.ModEtherInstruction(
166 L2ModificationInstruction.L2SubType.ETH_DST, addr);
alshabib55a55d92014-09-16 11:59:31 -0700167 }
168
169 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800170 * Creates a VLAN ID modification.
171 *
172 * @param vlanId the VLAN ID to modify to
alshabib7410fea2014-09-16 13:48:39 -0700173 * @return a L2 modification
174 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700175 public static L2ModificationInstruction modVlanId(VlanId vlanId) {
alshabib55a55d92014-09-16 11:59:31 -0700176 checkNotNull(vlanId, "VLAN id cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700177 return new L2ModificationInstruction.ModVlanIdInstruction(vlanId);
alshabib55a55d92014-09-16 11:59:31 -0700178 }
179
alshabib7410fea2014-09-16 13:48:39 -0700180 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800181 * Creates a VLAN PCP modification.
182 *
183 * @param vlanPcp the PCP to modify to
alshabib7410fea2014-09-16 13:48:39 -0700184 * @return a L2 modification
185 */
186 public static L2ModificationInstruction modVlanPcp(Byte vlanPcp) {
187 checkNotNull(vlanPcp, "VLAN Pcp cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700188 return new L2ModificationInstruction.ModVlanPcpInstruction(vlanPcp);
alshabib7410fea2014-09-16 13:48:39 -0700189 }
190
191 /**
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800192 * Creates a MPLS label modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800193 *
194 * @param mplsLabel MPLS label to set
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800195 * @return a L2 Modification
196 */
Michele Santuari4b6019e2014-12-19 11:31:45 +0100197 public static L2ModificationInstruction modMplsLabel(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800198 checkNotNull(mplsLabel, "MPLS label cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700199 return new L2ModificationInstruction.ModMplsLabelInstruction(mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800200 }
sangho3f97a17d2015-01-29 22:56:29 -0800201
202 /**
Saurav Das73a7dd42015-08-19 22:20:31 -0700203 * Creates a MPLS BOS bit modification.
204 *
205 * @param mplsBos MPLS BOS bit to set (true) or unset (false)
206 * @return a L2 Modification
207 */
208 public static L2ModificationInstruction modMplsBos(boolean mplsBos) {
209 return new L2ModificationInstruction.ModMplsBosInstruction(mplsBos);
210 }
211
212 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800213 * Creates a MPLS decrement TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800214 *
215 * @return a L2 Modification
216 */
217 public static L2ModificationInstruction decMplsTtl() {
alshabibd17abc22015-04-21 18:26:35 -0700218 return new L2ModificationInstruction.ModMplsTtlInstruction();
sangho3f97a17d2015-01-29 22:56:29 -0800219 }
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800220
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800221 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800222 * Creates a L3 IPv4 src modification.
223 *
224 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700225 * @return a L3 modification
226 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700227 public static L3ModificationInstruction modL3Src(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800228 checkNotNull(addr, "Src l3 IPv4 address cannot be null");
229 return new ModIPInstruction(L3SubType.IPV4_SRC, addr);
alshabib7410fea2014-09-16 13:48:39 -0700230 }
231
232 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800233 * Creates a L3 IPv4 dst modification.
234 *
235 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700236 * @return a L3 modification
237 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700238 public static L3ModificationInstruction modL3Dst(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800239 checkNotNull(addr, "Dst l3 IPv4 address cannot be null");
240 return new ModIPInstruction(L3SubType.IPV4_DST, addr);
241 }
242
243 /**
244 * Creates a L3 IPv6 src modification.
245 *
246 * @param addr the IPv6 address to modify to
247 * @return a L3 modification
248 */
249 public static L3ModificationInstruction modL3IPv6Src(IpAddress addr) {
250 checkNotNull(addr, "Src l3 IPv6 address cannot be null");
251 return new ModIPInstruction(L3SubType.IPV6_SRC, addr);
252 }
253
254 /**
255 * Creates a L3 IPv6 dst modification.
256 *
257 * @param addr the IPv6 address to modify to
258 * @return a L3 modification
259 */
260 public static L3ModificationInstruction modL3IPv6Dst(IpAddress addr) {
261 checkNotNull(addr, "Dst l3 IPv6 address cannot be null");
262 return new ModIPInstruction(L3SubType.IPV6_DST, addr);
263 }
264
265 /**
266 * Creates a L3 IPv6 Flow Label modification.
267 *
268 * @param flowLabel the IPv6 flow label to modify to (20 bits)
269 * @return a L3 modification
270 */
271 public static L3ModificationInstruction modL3IPv6FlowLabel(int flowLabel) {
272 return new ModIPv6FlowLabelInstruction(flowLabel);
alshabib7410fea2014-09-16 13:48:39 -0700273 }
274
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800275 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800276 * Creates a L3 decrement TTL modification.
277 *
sangho3f97a17d2015-01-29 22:56:29 -0800278 * @return a L3 modification
279 */
280 public static L3ModificationInstruction decNwTtl() {
281 return new ModTtlInstruction(L3SubType.DEC_TTL);
282 }
283
284 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800285 * Creates a L3 copy TTL to outer header modification.
286 *
sangho3f97a17d2015-01-29 22:56:29 -0800287 * @return a L3 modification
288 */
289 public static L3ModificationInstruction copyTtlOut() {
290 return new ModTtlInstruction(L3SubType.TTL_OUT);
291 }
292
293 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800294 * Creates a L3 copy TTL to inner header modification.
295 *
sangho3f97a17d2015-01-29 22:56:29 -0800296 * @return a L3 modification
297 */
298 public static L3ModificationInstruction copyTtlIn() {
299 return new ModTtlInstruction(L3SubType.TTL_IN);
300 }
301
302 /**
lishuai3cce60b2015-12-01 19:35:16 +0800303 * Creates a L3 ARP IP src modification.
304 *
305 * @param addr the ip address to modify to
306 * @return a L3 modification
307 */
308 public static L3ModificationInstruction modArpSpa(IpAddress addr) {
309 checkNotNull(addr, "Src l3 ARP IP address cannot be null");
310 return new ModArpIPInstruction(L3SubType.ARP_SPA, addr);
311 }
312
313 /**
314 * Creates a l3 ARP Ether src modification.
315 *
316 * @param addr the mac address to modify to
317 * @return a l3 modification
318 */
319 public static L3ModificationInstruction modArpSha(MacAddress addr) {
320 checkNotNull(addr, "Src l3 ARP address cannot be null");
321 return new ModArpEthInstruction(L3SubType.ARP_SHA, addr);
322 }
323
324 /**
325 * Creates a l3 ARP operation modification.
326 *
327 * @param op the ARP operation to modify to
328 * @return a l3 modification
329 */
330 public static L3ModificationInstruction modL3ArpOp(short op) {
331 checkNotNull(op, "Arp operation cannot be null");
332 return new ModArpOpInstruction(L3SubType.ARP_OP, op);
333 }
334
335 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800336 * Creates a push MPLS header instruction.
337 *
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800338 * @return a L2 modification.
339 */
340 public static Instruction pushMpls() {
alshabibd17abc22015-04-21 18:26:35 -0700341 return new L2ModificationInstruction.PushHeaderInstructions(
342 L2ModificationInstruction.L2SubType.MPLS_PUSH,
alshabib7b808c52015-06-26 14:22:24 -0700343 EthType.EtherType.MPLS_UNICAST.ethType());
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800344 }
345
346 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800347 * Creates a pop MPLS header instruction.
348 *
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800349 * @return a L2 modification.
350 */
351 public static Instruction popMpls() {
alshabibd17abc22015-04-21 18:26:35 -0700352 return new L2ModificationInstruction.PushHeaderInstructions(
353 L2ModificationInstruction.L2SubType.MPLS_POP,
alshabib7b808c52015-06-26 14:22:24 -0700354 EthType.EtherType.MPLS_UNICAST.ethType());
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800355 }
alshabib7410fea2014-09-16 13:48:39 -0700356
sangho3f97a17d2015-01-29 22:56:29 -0800357 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800358 * Creates a pop MPLS header instruction with a particular ethertype.
sangho3f97a17d2015-01-29 22:56:29 -0800359 *
360 * @param etherType Ethernet type to set
361 * @return a L2 modification.
alshabib7b808c52015-06-26 14:22:24 -0700362 */
363 public static Instruction popMpls(EthType etherType) {
364 checkNotNull(etherType, "Ethernet type cannot be null");
365 return new L2ModificationInstruction.PushHeaderInstructions(
alshabibd17abc22015-04-21 18:26:35 -0700366 L2ModificationInstruction.L2SubType.MPLS_POP, etherType);
sangho3f97a17d2015-01-29 22:56:29 -0800367 }
368
Saurav Dasfbe25c52015-03-04 11:12:00 -0800369 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800370 * Creates a pop VLAN header instruction.
371 *
372 * @return a L2 modification
Saurav Dasfbe25c52015-03-04 11:12:00 -0800373 */
374 public static Instruction popVlan() {
alshabibd17abc22015-04-21 18:26:35 -0700375 return new L2ModificationInstruction.PopVlanInstruction(
376 L2ModificationInstruction.L2SubType.VLAN_POP);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800377 }
378
379 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800380 * Creates a push VLAN header instruction.
381 *
382 * @return a L2 modification
383 */
384 public static Instruction pushVlan() {
alshabibd17abc22015-04-21 18:26:35 -0700385 return new L2ModificationInstruction.PushHeaderInstructions(
alshabib7b808c52015-06-26 14:22:24 -0700386 L2ModificationInstruction.L2SubType.VLAN_PUSH,
387 EthType.EtherType.VLAN.ethType());
Jonathan Hart54b406b2015-03-06 16:24:14 -0800388 }
389
390 /**
alshabibd17abc22015-04-21 18:26:35 -0700391 * Sends the packet to the table id.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800392 *
alshabibd17abc22015-04-21 18:26:35 -0700393 * @param tableId flow rule table id
Thomas Vachuska3e2b6512015-03-05 09:25:03 -0800394 * @return table type transition instruction
Saurav Dasfbe25c52015-03-04 11:12:00 -0800395 */
alshabibd17abc22015-04-21 18:26:35 -0700396 public static Instruction transition(Integer tableId) {
397 checkNotNull(tableId, "Table id cannot be null");
398 return new TableTypeTransition(tableId);
alshabib9af70072015-02-09 14:34:16 -0800399 }
400
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800401 /**
Saurav Das86af8f12015-05-25 23:55:33 -0700402 * Writes metadata to associate with a packet.
403 *
404 * @param metadata the metadata value to write
405 * @param metadataMask the bits to mask for the metadata value
406 * @return metadata instruction
407 */
408 public static Instruction writeMetadata(long metadata, long metadataMask) {
409 return new MetadataInstruction(metadata, metadataMask);
410 }
411
412 /**
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700413 * Creates a Tunnel ID modification.
414 *
415 * @param tunnelId the Tunnel ID to modify to
416 * @return a L2 modification
417 */
418 public static L2ModificationInstruction modTunnelId(long tunnelId) {
419 checkNotNull(tunnelId, "Tunnel id cannot be null");
420 return new L2ModificationInstruction.ModTunnelIdInstruction(tunnelId);
421 }
422
423 /**
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700424 * Creates a TCP src modification.
425 *
426 * @param port the TCP port number to modify to
427 * @return a L4 modification
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700428 */
429 public static L4ModificationInstruction modTcpSrc(TpPort port) {
430 checkNotNull(port, "Src TCP port cannot be null");
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700431 return new ModTransportPortInstruction(L4SubType.TCP_SRC, port);
432 }
433
434 /**
435 * Creates a TCP dst modification.
436 *
437 * @param port the TCP port number to modify to
438 * @return a L4 modification
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700439 */
440 public static L4ModificationInstruction modTcpDst(TpPort port) {
441 checkNotNull(port, "Dst TCP port cannot be null");
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700442 return new ModTransportPortInstruction(L4SubType.TCP_DST, port);
443 }
444
445 /**
446 * Creates a UDP src modification.
447 *
448 * @param port the UDP port number to modify to
449 * @return a L4 modification
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700450 */
451 public static L4ModificationInstruction modUdpSrc(TpPort port) {
452 checkNotNull(port, "Src UDP port cannot be null");
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700453 return new ModTransportPortInstruction(L4SubType.UDP_SRC, port);
454 }
455
456 /**
457 * Creates a UDP dst modification.
458 *
459 * @param port the UDP port number to modify to
460 * @return a L4 modification
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700461 */
462 public static L4ModificationInstruction modUdpDst(TpPort port) {
463 checkNotNull(port, "Dst UDP port cannot be null");
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700464 return new ModTransportPortInstruction(L4SubType.UDP_DST, port);
465 }
466
467 /**
Jonathan Hart3c259162015-10-21 21:31:19 -0700468 * Creates an extension instruction.
469 *
470 * @param extension extension instruction
471 * @param deviceId device ID
472 * @return extension instruction
473 */
alshabib880b6442015-11-23 22:13:04 -0800474 public static ExtensionInstructionWrapper extension(ExtensionTreatment extension,
Jonathan Hart3c259162015-10-21 21:31:19 -0700475 DeviceId deviceId) {
476 checkNotNull(extension, "Extension instruction cannot be null");
477 checkNotNull(deviceId, "Device ID cannot be null");
478 return new ExtensionInstructionWrapper(extension, deviceId);
479 }
480
481 /**
Charles Chan7efabeb2015-09-28 15:12:19 -0700482 * No Action instruction.
483 */
484 public static final class NoActionInstruction implements Instruction {
485
486 private NoActionInstruction() {}
487
488 @Override
489 public Type type() {
490 return Type.NOACTION;
491 }
492
493 @Override
494 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800495 return type().toString();
Charles Chan7efabeb2015-09-28 15:12:19 -0700496 }
497
498 @Override
499 public int hashCode() {
HIGUCHI Yutaca9cc8e2015-10-29 23:26:51 -0700500 return type().ordinal();
Charles Chan7efabeb2015-09-28 15:12:19 -0700501 }
502
503 @Override
504 public boolean equals(Object obj) {
505 if (this == obj) {
506 return true;
507 }
508 if (obj instanceof NoActionInstruction) {
509 return true;
510 }
511 return false;
512 }
513 }
514
515 /**
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800516 * Output Instruction.
sangho8995ac52015-02-04 11:29:03 -0800517 */
alshabib55a55d92014-09-16 11:59:31 -0700518 public static final class OutputInstruction implements Instruction {
519 private final PortNumber port;
520
521 private OutputInstruction(PortNumber port) {
522 this.port = port;
523 }
524
525 public PortNumber port() {
526 return port;
527 }
528
529 @Override
530 public Type type() {
531 return Type.OUTPUT;
532 }
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800533
alshabib99b8fdc2014-09-25 14:30:22 -0700534 @Override
535 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800536 return type().toString() + SEPARATOR + port.toString();
alshabib99b8fdc2014-09-25 14:30:22 -0700537 }
alshabib8ca53902014-10-07 13:11:17 -0700538
539 @Override
540 public int hashCode() {
Thomas Vachuska6c8eff32015-05-27 16:11:44 -0700541 return Objects.hash(type().ordinal(), port);
alshabib8ca53902014-10-07 13:11:17 -0700542 }
543
544 @Override
545 public boolean equals(Object obj) {
546 if (this == obj) {
547 return true;
548 }
549 if (obj instanceof OutputInstruction) {
550 OutputInstruction that = (OutputInstruction) obj;
Yuta HIGUCHI4ce65292014-11-01 12:09:55 -0700551 return Objects.equals(port, that.port);
alshabib8ca53902014-10-07 13:11:17 -0700552
553 }
554 return false;
555 }
alshabib55a55d92014-09-16 11:59:31 -0700556 }
557
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800558 /**
559 * Group Instruction.
sangho8995ac52015-02-04 11:29:03 -0800560 */
sangho8995ac52015-02-04 11:29:03 -0800561 public static final class GroupInstruction implements Instruction {
562 private final GroupId groupId;
563
564 private GroupInstruction(GroupId groupId) {
565 this.groupId = groupId;
566 }
567
568 public GroupId groupId() {
569 return groupId;
570 }
571
572 @Override
573 public Type type() {
574 return Type.GROUP;
575 }
alshabib9af70072015-02-09 14:34:16 -0800576
sangho8995ac52015-02-04 11:29:03 -0800577 @Override
578 public String toString() {
Saurav Das0fd79d92016-03-07 10:58:36 -0800579 return type().toString() + SEPARATOR + "0x" + Integer.toHexString(groupId.id());
sangho8995ac52015-02-04 11:29:03 -0800580 }
581
582 @Override
583 public int hashCode() {
Thomas Vachuska6c8eff32015-05-27 16:11:44 -0700584 return Objects.hash(type().ordinal(), groupId);
sangho8995ac52015-02-04 11:29:03 -0800585 }
586
587 @Override
588 public boolean equals(Object obj) {
589 if (this == obj) {
590 return true;
591 }
592 if (obj instanceof GroupInstruction) {
593 GroupInstruction that = (GroupInstruction) obj;
594 return Objects.equals(groupId, that.groupId);
595
596 }
597 return false;
598 }
599 }
600
Saurav Das86af8f12015-05-25 23:55:33 -0700601 /**
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200602 * Set-Queue Instruction.
603 */
604 public static final class SetQueueInstruction implements Instruction {
605 private final long queueId;
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200606 private final PortNumber port;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200607
608 private SetQueueInstruction(long queueId) {
609 this.queueId = queueId;
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200610 this.port = null;
611 }
612
613 private SetQueueInstruction(long queueId, PortNumber port) {
614 this.queueId = queueId;
615 this.port = port;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200616 }
617
618 public long queueId() {
619 return queueId;
620 }
621
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200622 public PortNumber port() {
623 return port;
624 }
625
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200626 @Override
627 public Type type() {
628 return Type.QUEUE;
629 }
630
631 @Override
632 public String toString() {
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200633 MoreObjects.ToStringHelper toStringHelper = toStringHelper(type().toString());
634 toStringHelper.add("queueId", queueId);
635
636 if (port() != null) {
637 toStringHelper.add("port", port);
638 }
639 return toStringHelper.toString();
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200640 }
641
642 @Override
643 public int hashCode() {
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200644 return Objects.hash(type().ordinal(), queueId, port);
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200645 }
646
647 @Override
648 public boolean equals(Object obj) {
649 if (this == obj) {
650 return true;
651 }
652 if (obj instanceof SetQueueInstruction) {
653 SetQueueInstruction that = (SetQueueInstruction) obj;
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200654 return Objects.equals(queueId, that.queueId) && Objects.equals(port, that.port);
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200655
656 }
657 return false;
658 }
659 }
660
661 /**
alshabib10c810b2015-08-18 16:59:04 -0700662 * A meter instruction.
663 */
664 public static final class MeterInstruction implements Instruction {
665 private final MeterId meterId;
666
667 private MeterInstruction(MeterId meterId) {
668 this.meterId = meterId;
669 }
670
671 public MeterId meterId() {
672 return meterId;
673 }
674
675 @Override
676 public Type type() {
677 return Type.METER;
678 }
679
680 @Override
681 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800682 return type().toString() + SEPARATOR + meterId.id();
alshabib10c810b2015-08-18 16:59:04 -0700683 }
684
685 @Override
686 public int hashCode() {
687 return Objects.hash(type().ordinal(), meterId);
688 }
689
690 @Override
691 public boolean equals(Object obj) {
692 if (this == obj) {
693 return true;
694 }
695 if (obj instanceof MeterInstruction) {
696 MeterInstruction that = (MeterInstruction) obj;
697 return Objects.equals(meterId, that.meterId);
698
699 }
700 return false;
701 }
702 }
703
704 /**
Saurav Das86af8f12015-05-25 23:55:33 -0700705 * Transition instruction.
706 */
alshabibd17abc22015-04-21 18:26:35 -0700707 public static class TableTypeTransition implements Instruction {
708 private final Integer tableId;
709
710 TableTypeTransition(Integer tableId) {
711 this.tableId = tableId;
alshabib9af70072015-02-09 14:34:16 -0800712 }
713
714 @Override
715 public Type type() {
716 return Type.TABLE;
717 }
718
alshabibd17abc22015-04-21 18:26:35 -0700719 public Integer tableId() {
720 return this.tableId;
alshabib9af70072015-02-09 14:34:16 -0800721 }
722
723 @Override
724 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800725 return type().toString() + SEPARATOR + this.tableId;
alshabib9af70072015-02-09 14:34:16 -0800726 }
727
728 @Override
729 public int hashCode() {
Thomas Vachuska6c8eff32015-05-27 16:11:44 -0700730 return Objects.hash(type().ordinal(), tableId);
alshabib9af70072015-02-09 14:34:16 -0800731 }
732
733 @Override
734 public boolean equals(Object obj) {
735 if (this == obj) {
736 return true;
737 }
738 if (obj instanceof TableTypeTransition) {
739 TableTypeTransition that = (TableTypeTransition) obj;
alshabibd17abc22015-04-21 18:26:35 -0700740 return Objects.equals(tableId, that.tableId);
alshabib9af70072015-02-09 14:34:16 -0800741
742 }
743 return false;
744 }
Saurav Das86af8f12015-05-25 23:55:33 -0700745 }
alshabib9af70072015-02-09 14:34:16 -0800746
Saurav Das86af8f12015-05-25 23:55:33 -0700747 /**
748 * Metadata instruction.
749 */
750 public static class MetadataInstruction implements Instruction {
751 private final long metadata;
752 private final long metadataMask;
753
754 MetadataInstruction(long metadata, long metadataMask) {
755 this.metadata = metadata;
756 this.metadataMask = metadataMask;
757 }
758
759 @Override
760 public Type type() {
761 return Type.METADATA;
762 }
763
764 public long metadata() {
765 return this.metadata;
766 }
767
768 public long metadataMask() {
769 return this.metadataMask;
770 }
771
772 @Override
773 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800774 return type().toString() + SEPARATOR +
775 Long.toHexString(this.metadata) + "/" +
776 Long.toHexString(this.metadataMask);
Saurav Das86af8f12015-05-25 23:55:33 -0700777 }
778
779 @Override
780 public int hashCode() {
Thomas Vachuska6c8eff32015-05-27 16:11:44 -0700781 return Objects.hash(type().ordinal(), metadata, metadataMask);
Saurav Das86af8f12015-05-25 23:55:33 -0700782 }
783
784 @Override
785 public boolean equals(Object obj) {
786 if (this == obj) {
787 return true;
788 }
789 if (obj instanceof MetadataInstruction) {
790 MetadataInstruction that = (MetadataInstruction) obj;
791 return Objects.equals(metadata, that.metadata) &&
792 Objects.equals(metadataMask, that.metadataMask);
793
794 }
795 return false;
796 }
alshabib9af70072015-02-09 14:34:16 -0800797 }
Saurav Das73a7dd42015-08-19 22:20:31 -0700798
Jonathan Hart3c259162015-10-21 21:31:19 -0700799 /**
800 * Extension instruction.
801 */
802 public static class ExtensionInstructionWrapper implements Instruction {
alshabib880b6442015-11-23 22:13:04 -0800803 private final ExtensionTreatment extensionTreatment;
Jonathan Hart3c259162015-10-21 21:31:19 -0700804 private final DeviceId deviceId;
805
alshabib880b6442015-11-23 22:13:04 -0800806 ExtensionInstructionWrapper(ExtensionTreatment extension, DeviceId deviceId) {
807 extensionTreatment = extension;
Jonathan Hart3c259162015-10-21 21:31:19 -0700808 this.deviceId = deviceId;
809 }
810
alshabib880b6442015-11-23 22:13:04 -0800811 public ExtensionTreatment extensionInstruction() {
812 return extensionTreatment;
Jonathan Hart3c259162015-10-21 21:31:19 -0700813 }
814
815 public DeviceId deviceId() {
816 return deviceId;
817 }
818
819 @Override
820 public Type type() {
821 return Type.EXTENSION;
822 }
823
824 @Override
825 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800826 return type().toString() + SEPARATOR + deviceId + "/" + extensionTreatment;
Jonathan Hart3c259162015-10-21 21:31:19 -0700827 }
828
829 @Override
830 public int hashCode() {
alshabib880b6442015-11-23 22:13:04 -0800831 return Objects.hash(type().ordinal(), extensionTreatment, deviceId);
Jonathan Hart3c259162015-10-21 21:31:19 -0700832 }
833
834 @Override
835 public boolean equals(Object obj) {
836 if (this == obj) {
837 return true;
838 }
839 if (obj instanceof ExtensionInstructionWrapper) {
840 ExtensionInstructionWrapper that = (ExtensionInstructionWrapper) obj;
alshabib880b6442015-11-23 22:13:04 -0800841 return Objects.equals(extensionTreatment, that.extensionTreatment)
Jonathan Hart3c259162015-10-21 21:31:19 -0700842 && Objects.equals(deviceId, that.deviceId);
843
844 }
845 return false;
846 }
847 }
848
alshabib55a55d92014-09-16 11:59:31 -0700849}
alshabib8ca53902014-10-07 13:11:17 -0700850
851