blob: aef755fabe2c25da6513c0e413928363efc5fdbf [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
alshabib10c810b2015-08-18 16:59:04 -0700106 public static MeterInstruction meterTraffic(final MeterId meterId) {
107 checkNotNull(meterId, "meter id cannot be null");
108 return new MeterInstruction(meterId);
109 }
110
sangho8995ac52015-02-04 11:29:03 -0800111 /**
Sho SHIMIZUe9e12752015-05-05 14:45:40 -0700112 * Creates an L0 modification with the specified OCh signal.
113 *
114 * @param lambda OCh signal
115 * @return an L0 modification
116 */
Sho SHIMIZU2e7ac842015-05-05 15:45:38 -0700117 public static L0ModificationInstruction modL0Lambda(Lambda lambda) {
Sho SHIMIZUe9e12752015-05-05 14:45:40 -0700118 checkNotNull(lambda, "L0 OCh signal cannot be null");
Sho SHIMIZU2e7ac842015-05-05 15:45:38 -0700119
120 if (lambda instanceof IndexedLambda) {
121 return new ModLambdaInstruction(L0SubType.LAMBDA, (short) ((IndexedLambda) lambda).index());
122 } else if (lambda instanceof OchSignal) {
123 return new ModOchSignalInstruction((OchSignal) lambda);
124 } else {
125 throw new UnsupportedOperationException(String.format("Unsupported type: %s", lambda));
126 }
Sho SHIMIZUe9e12752015-05-05 14:45:40 -0700127 }
128
129 /**
Yafit Hadar52d81552015-10-07 12:26:52 +0300130 * Creates an L1 modification with the specified ODU signal Id.
131 *
132 * @param oduSignalId ODU Signal Id
133 * @return a L1 modification
134 */
135 public static L1ModificationInstruction modL1OduSignalId(OduSignalId oduSignalId) {
136 checkNotNull(oduSignalId, "L1 ODU signal ID cannot be null");
137 return new ModOduSignalIdInstruction(oduSignalId);
138 }
139 /**
alshabib55a55d92014-09-16 11:59:31 -0700140 * Creates a l2 src modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800141 *
142 * @param addr the mac address to modify to
alshabib55a55d92014-09-16 11:59:31 -0700143 * @return a l2 modification
144 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700145 public static L2ModificationInstruction modL2Src(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -0700146 checkNotNull(addr, "Src l2 address cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700147 return new L2ModificationInstruction.ModEtherInstruction(
148 L2ModificationInstruction.L2SubType.ETH_SRC, addr);
alshabib55a55d92014-09-16 11:59:31 -0700149 }
150
151 /**
152 * Creates a L2 dst modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800153 *
154 * @param addr the mac address to modify to
alshabib55a55d92014-09-16 11:59:31 -0700155 * @return a L2 modification
156 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700157 public static L2ModificationInstruction modL2Dst(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -0700158 checkNotNull(addr, "Dst l2 address cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700159 return new L2ModificationInstruction.ModEtherInstruction(
160 L2ModificationInstruction.L2SubType.ETH_DST, addr);
alshabib55a55d92014-09-16 11:59:31 -0700161 }
162
163 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800164 * Creates a VLAN ID modification.
165 *
166 * @param vlanId the VLAN ID to modify to
alshabib7410fea2014-09-16 13:48:39 -0700167 * @return a L2 modification
168 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700169 public static L2ModificationInstruction modVlanId(VlanId vlanId) {
alshabib55a55d92014-09-16 11:59:31 -0700170 checkNotNull(vlanId, "VLAN id cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700171 return new L2ModificationInstruction.ModVlanIdInstruction(vlanId);
alshabib55a55d92014-09-16 11:59:31 -0700172 }
173
alshabib7410fea2014-09-16 13:48:39 -0700174 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800175 * Creates a VLAN PCP modification.
176 *
177 * @param vlanPcp the PCP to modify to
alshabib7410fea2014-09-16 13:48:39 -0700178 * @return a L2 modification
179 */
180 public static L2ModificationInstruction modVlanPcp(Byte vlanPcp) {
181 checkNotNull(vlanPcp, "VLAN Pcp cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700182 return new L2ModificationInstruction.ModVlanPcpInstruction(vlanPcp);
alshabib7410fea2014-09-16 13:48:39 -0700183 }
184
185 /**
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800186 * Creates a MPLS label modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800187 *
188 * @param mplsLabel MPLS label to set
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800189 * @return a L2 Modification
190 */
Michele Santuari4b6019e2014-12-19 11:31:45 +0100191 public static L2ModificationInstruction modMplsLabel(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800192 checkNotNull(mplsLabel, "MPLS label cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700193 return new L2ModificationInstruction.ModMplsLabelInstruction(mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800194 }
sangho3f97a17d2015-01-29 22:56:29 -0800195
196 /**
Saurav Das73a7dd42015-08-19 22:20:31 -0700197 * Creates a MPLS BOS bit modification.
198 *
199 * @param mplsBos MPLS BOS bit to set (true) or unset (false)
200 * @return a L2 Modification
201 */
202 public static L2ModificationInstruction modMplsBos(boolean mplsBos) {
203 return new L2ModificationInstruction.ModMplsBosInstruction(mplsBos);
204 }
205
206 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800207 * Creates a MPLS decrement TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800208 *
209 * @return a L2 Modification
210 */
211 public static L2ModificationInstruction decMplsTtl() {
alshabibd17abc22015-04-21 18:26:35 -0700212 return new L2ModificationInstruction.ModMplsTtlInstruction();
sangho3f97a17d2015-01-29 22:56:29 -0800213 }
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800214
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800215 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800216 * Creates a L3 IPv4 src modification.
217 *
218 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700219 * @return a L3 modification
220 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700221 public static L3ModificationInstruction modL3Src(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800222 checkNotNull(addr, "Src l3 IPv4 address cannot be null");
223 return new ModIPInstruction(L3SubType.IPV4_SRC, addr);
alshabib7410fea2014-09-16 13:48:39 -0700224 }
225
226 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800227 * Creates a L3 IPv4 dst modification.
228 *
229 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700230 * @return a L3 modification
231 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700232 public static L3ModificationInstruction modL3Dst(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800233 checkNotNull(addr, "Dst l3 IPv4 address cannot be null");
234 return new ModIPInstruction(L3SubType.IPV4_DST, addr);
235 }
236
237 /**
238 * Creates a L3 IPv6 src modification.
239 *
240 * @param addr the IPv6 address to modify to
241 * @return a L3 modification
242 */
243 public static L3ModificationInstruction modL3IPv6Src(IpAddress addr) {
244 checkNotNull(addr, "Src l3 IPv6 address cannot be null");
245 return new ModIPInstruction(L3SubType.IPV6_SRC, addr);
246 }
247
248 /**
249 * Creates a L3 IPv6 dst modification.
250 *
251 * @param addr the IPv6 address to modify to
252 * @return a L3 modification
253 */
254 public static L3ModificationInstruction modL3IPv6Dst(IpAddress addr) {
255 checkNotNull(addr, "Dst l3 IPv6 address cannot be null");
256 return new ModIPInstruction(L3SubType.IPV6_DST, addr);
257 }
258
259 /**
260 * Creates a L3 IPv6 Flow Label modification.
261 *
262 * @param flowLabel the IPv6 flow label to modify to (20 bits)
263 * @return a L3 modification
264 */
265 public static L3ModificationInstruction modL3IPv6FlowLabel(int flowLabel) {
266 return new ModIPv6FlowLabelInstruction(flowLabel);
alshabib7410fea2014-09-16 13:48:39 -0700267 }
268
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800269 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800270 * Creates a L3 decrement TTL modification.
271 *
sangho3f97a17d2015-01-29 22:56:29 -0800272 * @return a L3 modification
273 */
274 public static L3ModificationInstruction decNwTtl() {
275 return new ModTtlInstruction(L3SubType.DEC_TTL);
276 }
277
278 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800279 * Creates a L3 copy TTL to outer header modification.
280 *
sangho3f97a17d2015-01-29 22:56:29 -0800281 * @return a L3 modification
282 */
283 public static L3ModificationInstruction copyTtlOut() {
284 return new ModTtlInstruction(L3SubType.TTL_OUT);
285 }
286
287 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800288 * Creates a L3 copy TTL to inner header modification.
289 *
sangho3f97a17d2015-01-29 22:56:29 -0800290 * @return a L3 modification
291 */
292 public static L3ModificationInstruction copyTtlIn() {
293 return new ModTtlInstruction(L3SubType.TTL_IN);
294 }
295
296 /**
lishuai3cce60b2015-12-01 19:35:16 +0800297 * Creates a L3 ARP IP src modification.
298 *
299 * @param addr the ip address to modify to
300 * @return a L3 modification
301 */
302 public static L3ModificationInstruction modArpSpa(IpAddress addr) {
303 checkNotNull(addr, "Src l3 ARP IP address cannot be null");
304 return new ModArpIPInstruction(L3SubType.ARP_SPA, addr);
305 }
306
307 /**
308 * Creates a l3 ARP Ether src modification.
309 *
310 * @param addr the mac address to modify to
311 * @return a l3 modification
312 */
313 public static L3ModificationInstruction modArpSha(MacAddress addr) {
314 checkNotNull(addr, "Src l3 ARP address cannot be null");
315 return new ModArpEthInstruction(L3SubType.ARP_SHA, addr);
316 }
317
318 /**
319 * Creates a l3 ARP operation modification.
320 *
321 * @param op the ARP operation to modify to
322 * @return a l3 modification
323 */
324 public static L3ModificationInstruction modL3ArpOp(short op) {
325 checkNotNull(op, "Arp operation cannot be null");
326 return new ModArpOpInstruction(L3SubType.ARP_OP, op);
327 }
328
329 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800330 * Creates a push MPLS header instruction.
331 *
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800332 * @return a L2 modification.
333 */
334 public static Instruction pushMpls() {
alshabibd17abc22015-04-21 18:26:35 -0700335 return new L2ModificationInstruction.PushHeaderInstructions(
336 L2ModificationInstruction.L2SubType.MPLS_PUSH,
alshabib7b808c52015-06-26 14:22:24 -0700337 EthType.EtherType.MPLS_UNICAST.ethType());
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800338 }
339
340 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800341 * Creates a pop MPLS header instruction.
342 *
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800343 * @return a L2 modification.
344 */
345 public static Instruction popMpls() {
alshabibd17abc22015-04-21 18:26:35 -0700346 return new L2ModificationInstruction.PushHeaderInstructions(
347 L2ModificationInstruction.L2SubType.MPLS_POP,
alshabib7b808c52015-06-26 14:22:24 -0700348 EthType.EtherType.MPLS_UNICAST.ethType());
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800349 }
alshabib7410fea2014-09-16 13:48:39 -0700350
sangho3f97a17d2015-01-29 22:56:29 -0800351 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800352 * Creates a pop MPLS header instruction with a particular ethertype.
sangho3f97a17d2015-01-29 22:56:29 -0800353 *
354 * @param etherType Ethernet type to set
355 * @return a L2 modification.
alshabib7b808c52015-06-26 14:22:24 -0700356 */
357 public static Instruction popMpls(EthType etherType) {
358 checkNotNull(etherType, "Ethernet type cannot be null");
359 return new L2ModificationInstruction.PushHeaderInstructions(
alshabibd17abc22015-04-21 18:26:35 -0700360 L2ModificationInstruction.L2SubType.MPLS_POP, etherType);
sangho3f97a17d2015-01-29 22:56:29 -0800361 }
362
Saurav Dasfbe25c52015-03-04 11:12:00 -0800363 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800364 * Creates a pop VLAN header instruction.
365 *
366 * @return a L2 modification
Saurav Dasfbe25c52015-03-04 11:12:00 -0800367 */
368 public static Instruction popVlan() {
alshabibd17abc22015-04-21 18:26:35 -0700369 return new L2ModificationInstruction.PopVlanInstruction(
370 L2ModificationInstruction.L2SubType.VLAN_POP);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800371 }
372
373 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800374 * Creates a push VLAN header instruction.
375 *
376 * @return a L2 modification
377 */
378 public static Instruction pushVlan() {
alshabibd17abc22015-04-21 18:26:35 -0700379 return new L2ModificationInstruction.PushHeaderInstructions(
alshabib7b808c52015-06-26 14:22:24 -0700380 L2ModificationInstruction.L2SubType.VLAN_PUSH,
381 EthType.EtherType.VLAN.ethType());
Jonathan Hart54b406b2015-03-06 16:24:14 -0800382 }
383
384 /**
alshabibd17abc22015-04-21 18:26:35 -0700385 * Sends the packet to the table id.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800386 *
alshabibd17abc22015-04-21 18:26:35 -0700387 * @param tableId flow rule table id
Thomas Vachuska3e2b6512015-03-05 09:25:03 -0800388 * @return table type transition instruction
Saurav Dasfbe25c52015-03-04 11:12:00 -0800389 */
alshabibd17abc22015-04-21 18:26:35 -0700390 public static Instruction transition(Integer tableId) {
391 checkNotNull(tableId, "Table id cannot be null");
392 return new TableTypeTransition(tableId);
alshabib9af70072015-02-09 14:34:16 -0800393 }
394
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800395 /**
Saurav Das86af8f12015-05-25 23:55:33 -0700396 * Writes metadata to associate with a packet.
397 *
398 * @param metadata the metadata value to write
399 * @param metadataMask the bits to mask for the metadata value
400 * @return metadata instruction
401 */
402 public static Instruction writeMetadata(long metadata, long metadataMask) {
403 return new MetadataInstruction(metadata, metadataMask);
404 }
405
406 /**
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700407 * Creates a Tunnel ID modification.
408 *
409 * @param tunnelId the Tunnel ID to modify to
410 * @return a L2 modification
411 */
412 public static L2ModificationInstruction modTunnelId(long tunnelId) {
413 checkNotNull(tunnelId, "Tunnel id cannot be null");
414 return new L2ModificationInstruction.ModTunnelIdInstruction(tunnelId);
415 }
416
417 /**
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700418 * Creates a TCP src modification.
419 *
420 * @param port the TCP port number to modify to
421 * @return a L4 modification
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700422 */
423 public static L4ModificationInstruction modTcpSrc(TpPort port) {
424 checkNotNull(port, "Src TCP port cannot be null");
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700425 return new ModTransportPortInstruction(L4SubType.TCP_SRC, port);
426 }
427
428 /**
429 * Creates a TCP dst modification.
430 *
431 * @param port the TCP port number to modify to
432 * @return a L4 modification
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700433 */
434 public static L4ModificationInstruction modTcpDst(TpPort port) {
435 checkNotNull(port, "Dst TCP port cannot be null");
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700436 return new ModTransportPortInstruction(L4SubType.TCP_DST, port);
437 }
438
439 /**
440 * Creates a UDP src modification.
441 *
442 * @param port the UDP port number to modify to
443 * @return a L4 modification
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700444 */
445 public static L4ModificationInstruction modUdpSrc(TpPort port) {
446 checkNotNull(port, "Src UDP port cannot be null");
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700447 return new ModTransportPortInstruction(L4SubType.UDP_SRC, port);
448 }
449
450 /**
451 * Creates a UDP dst modification.
452 *
453 * @param port the UDP port number to modify to
454 * @return a L4 modification
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700455 */
456 public static L4ModificationInstruction modUdpDst(TpPort port) {
457 checkNotNull(port, "Dst UDP port cannot be null");
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700458 return new ModTransportPortInstruction(L4SubType.UDP_DST, port);
459 }
460
461 /**
Jonathan Hart3c259162015-10-21 21:31:19 -0700462 * Creates an extension instruction.
463 *
464 * @param extension extension instruction
465 * @param deviceId device ID
466 * @return extension instruction
467 */
alshabib880b6442015-11-23 22:13:04 -0800468 public static ExtensionInstructionWrapper extension(ExtensionTreatment extension,
Jonathan Hart3c259162015-10-21 21:31:19 -0700469 DeviceId deviceId) {
470 checkNotNull(extension, "Extension instruction cannot be null");
471 checkNotNull(deviceId, "Device ID cannot be null");
472 return new ExtensionInstructionWrapper(extension, deviceId);
473 }
474
475 /**
Charles Chan7efabeb2015-09-28 15:12:19 -0700476 * No Action instruction.
477 */
478 public static final class NoActionInstruction implements Instruction {
479
480 private NoActionInstruction() {}
481
482 @Override
483 public Type type() {
484 return Type.NOACTION;
485 }
486
487 @Override
488 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800489 return type().toString();
Charles Chan7efabeb2015-09-28 15:12:19 -0700490 }
491
492 @Override
493 public int hashCode() {
HIGUCHI Yutaca9cc8e2015-10-29 23:26:51 -0700494 return type().ordinal();
Charles Chan7efabeb2015-09-28 15:12:19 -0700495 }
496
497 @Override
498 public boolean equals(Object obj) {
499 if (this == obj) {
500 return true;
501 }
502 if (obj instanceof NoActionInstruction) {
503 return true;
504 }
505 return false;
506 }
507 }
508
509 /**
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800510 * Output Instruction.
sangho8995ac52015-02-04 11:29:03 -0800511 */
alshabib55a55d92014-09-16 11:59:31 -0700512 public static final class OutputInstruction implements Instruction {
513 private final PortNumber port;
514
515 private OutputInstruction(PortNumber port) {
516 this.port = port;
517 }
518
519 public PortNumber port() {
520 return port;
521 }
522
523 @Override
524 public Type type() {
525 return Type.OUTPUT;
526 }
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800527
alshabib99b8fdc2014-09-25 14:30:22 -0700528 @Override
529 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800530 return type().toString() + SEPARATOR + port.toString();
alshabib99b8fdc2014-09-25 14:30:22 -0700531 }
alshabib8ca53902014-10-07 13:11:17 -0700532
533 @Override
534 public int hashCode() {
Thomas Vachuska6c8eff32015-05-27 16:11:44 -0700535 return Objects.hash(type().ordinal(), port);
alshabib8ca53902014-10-07 13:11:17 -0700536 }
537
538 @Override
539 public boolean equals(Object obj) {
540 if (this == obj) {
541 return true;
542 }
543 if (obj instanceof OutputInstruction) {
544 OutputInstruction that = (OutputInstruction) obj;
Yuta HIGUCHI4ce65292014-11-01 12:09:55 -0700545 return Objects.equals(port, that.port);
alshabib8ca53902014-10-07 13:11:17 -0700546
547 }
548 return false;
549 }
alshabib55a55d92014-09-16 11:59:31 -0700550 }
551
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800552 /**
553 * Group Instruction.
sangho8995ac52015-02-04 11:29:03 -0800554 */
sangho8995ac52015-02-04 11:29:03 -0800555 public static final class GroupInstruction implements Instruction {
556 private final GroupId groupId;
557
558 private GroupInstruction(GroupId groupId) {
559 this.groupId = groupId;
560 }
561
562 public GroupId groupId() {
563 return groupId;
564 }
565
566 @Override
567 public Type type() {
568 return Type.GROUP;
569 }
alshabib9af70072015-02-09 14:34:16 -0800570
sangho8995ac52015-02-04 11:29:03 -0800571 @Override
572 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800573 return type().toString() + SEPARATOR + Integer.toHexString(groupId.id());
sangho8995ac52015-02-04 11:29:03 -0800574 }
575
576 @Override
577 public int hashCode() {
Thomas Vachuska6c8eff32015-05-27 16:11:44 -0700578 return Objects.hash(type().ordinal(), groupId);
sangho8995ac52015-02-04 11:29:03 -0800579 }
580
581 @Override
582 public boolean equals(Object obj) {
583 if (this == obj) {
584 return true;
585 }
586 if (obj instanceof GroupInstruction) {
587 GroupInstruction that = (GroupInstruction) obj;
588 return Objects.equals(groupId, that.groupId);
589
590 }
591 return false;
592 }
593 }
594
Saurav Das86af8f12015-05-25 23:55:33 -0700595 /**
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200596 * Set-Queue Instruction.
597 */
598 public static final class SetQueueInstruction implements Instruction {
599 private final long queueId;
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200600 private final PortNumber port;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200601
602 private SetQueueInstruction(long queueId) {
603 this.queueId = queueId;
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200604 this.port = null;
605 }
606
607 private SetQueueInstruction(long queueId, PortNumber port) {
608 this.queueId = queueId;
609 this.port = port;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200610 }
611
612 public long queueId() {
613 return queueId;
614 }
615
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200616 public PortNumber port() {
617 return port;
618 }
619
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200620 @Override
621 public Type type() {
622 return Type.QUEUE;
623 }
624
625 @Override
626 public String toString() {
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200627 MoreObjects.ToStringHelper toStringHelper = toStringHelper(type().toString());
628 toStringHelper.add("queueId", queueId);
629
630 if (port() != null) {
631 toStringHelper.add("port", port);
632 }
633 return toStringHelper.toString();
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200634 }
635
636 @Override
637 public int hashCode() {
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200638 return Objects.hash(type().ordinal(), queueId, port);
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200639 }
640
641 @Override
642 public boolean equals(Object obj) {
643 if (this == obj) {
644 return true;
645 }
646 if (obj instanceof SetQueueInstruction) {
647 SetQueueInstruction that = (SetQueueInstruction) obj;
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200648 return Objects.equals(queueId, that.queueId) && Objects.equals(port, that.port);
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200649
650 }
651 return false;
652 }
653 }
654
655 /**
alshabib10c810b2015-08-18 16:59:04 -0700656 * A meter instruction.
657 */
658 public static final class MeterInstruction implements Instruction {
659 private final MeterId meterId;
660
661 private MeterInstruction(MeterId meterId) {
662 this.meterId = meterId;
663 }
664
665 public MeterId meterId() {
666 return meterId;
667 }
668
669 @Override
670 public Type type() {
671 return Type.METER;
672 }
673
674 @Override
675 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800676 return type().toString() + SEPARATOR + meterId.id();
alshabib10c810b2015-08-18 16:59:04 -0700677 }
678
679 @Override
680 public int hashCode() {
681 return Objects.hash(type().ordinal(), meterId);
682 }
683
684 @Override
685 public boolean equals(Object obj) {
686 if (this == obj) {
687 return true;
688 }
689 if (obj instanceof MeterInstruction) {
690 MeterInstruction that = (MeterInstruction) obj;
691 return Objects.equals(meterId, that.meterId);
692
693 }
694 return false;
695 }
696 }
697
698 /**
Saurav Das86af8f12015-05-25 23:55:33 -0700699 * Transition instruction.
700 */
alshabibd17abc22015-04-21 18:26:35 -0700701 public static class TableTypeTransition implements Instruction {
702 private final Integer tableId;
703
704 TableTypeTransition(Integer tableId) {
705 this.tableId = tableId;
alshabib9af70072015-02-09 14:34:16 -0800706 }
707
708 @Override
709 public Type type() {
710 return Type.TABLE;
711 }
712
alshabibd17abc22015-04-21 18:26:35 -0700713 public Integer tableId() {
714 return this.tableId;
alshabib9af70072015-02-09 14:34:16 -0800715 }
716
717 @Override
718 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800719 return type().toString() + SEPARATOR + this.tableId;
alshabib9af70072015-02-09 14:34:16 -0800720 }
721
722 @Override
723 public int hashCode() {
Thomas Vachuska6c8eff32015-05-27 16:11:44 -0700724 return Objects.hash(type().ordinal(), tableId);
alshabib9af70072015-02-09 14:34:16 -0800725 }
726
727 @Override
728 public boolean equals(Object obj) {
729 if (this == obj) {
730 return true;
731 }
732 if (obj instanceof TableTypeTransition) {
733 TableTypeTransition that = (TableTypeTransition) obj;
alshabibd17abc22015-04-21 18:26:35 -0700734 return Objects.equals(tableId, that.tableId);
alshabib9af70072015-02-09 14:34:16 -0800735
736 }
737 return false;
738 }
Saurav Das86af8f12015-05-25 23:55:33 -0700739 }
alshabib9af70072015-02-09 14:34:16 -0800740
Saurav Das86af8f12015-05-25 23:55:33 -0700741 /**
742 * Metadata instruction.
743 */
744 public static class MetadataInstruction implements Instruction {
745 private final long metadata;
746 private final long metadataMask;
747
748 MetadataInstruction(long metadata, long metadataMask) {
749 this.metadata = metadata;
750 this.metadataMask = metadataMask;
751 }
752
753 @Override
754 public Type type() {
755 return Type.METADATA;
756 }
757
758 public long metadata() {
759 return this.metadata;
760 }
761
762 public long metadataMask() {
763 return this.metadataMask;
764 }
765
766 @Override
767 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800768 return type().toString() + SEPARATOR +
769 Long.toHexString(this.metadata) + "/" +
770 Long.toHexString(this.metadataMask);
Saurav Das86af8f12015-05-25 23:55:33 -0700771 }
772
773 @Override
774 public int hashCode() {
Thomas Vachuska6c8eff32015-05-27 16:11:44 -0700775 return Objects.hash(type().ordinal(), metadata, metadataMask);
Saurav Das86af8f12015-05-25 23:55:33 -0700776 }
777
778 @Override
779 public boolean equals(Object obj) {
780 if (this == obj) {
781 return true;
782 }
783 if (obj instanceof MetadataInstruction) {
784 MetadataInstruction that = (MetadataInstruction) obj;
785 return Objects.equals(metadata, that.metadata) &&
786 Objects.equals(metadataMask, that.metadataMask);
787
788 }
789 return false;
790 }
alshabib9af70072015-02-09 14:34:16 -0800791 }
Saurav Das73a7dd42015-08-19 22:20:31 -0700792
Jonathan Hart3c259162015-10-21 21:31:19 -0700793 /**
794 * Extension instruction.
795 */
796 public static class ExtensionInstructionWrapper implements Instruction {
alshabib880b6442015-11-23 22:13:04 -0800797 private final ExtensionTreatment extensionTreatment;
Jonathan Hart3c259162015-10-21 21:31:19 -0700798 private final DeviceId deviceId;
799
alshabib880b6442015-11-23 22:13:04 -0800800 ExtensionInstructionWrapper(ExtensionTreatment extension, DeviceId deviceId) {
801 extensionTreatment = extension;
Jonathan Hart3c259162015-10-21 21:31:19 -0700802 this.deviceId = deviceId;
803 }
804
alshabib880b6442015-11-23 22:13:04 -0800805 public ExtensionTreatment extensionInstruction() {
806 return extensionTreatment;
Jonathan Hart3c259162015-10-21 21:31:19 -0700807 }
808
809 public DeviceId deviceId() {
810 return deviceId;
811 }
812
813 @Override
814 public Type type() {
815 return Type.EXTENSION;
816 }
817
818 @Override
819 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800820 return type().toString() + SEPARATOR + deviceId + "/" + extensionTreatment;
Jonathan Hart3c259162015-10-21 21:31:19 -0700821 }
822
823 @Override
824 public int hashCode() {
alshabib880b6442015-11-23 22:13:04 -0800825 return Objects.hash(type().ordinal(), extensionTreatment, deviceId);
Jonathan Hart3c259162015-10-21 21:31:19 -0700826 }
827
828 @Override
829 public boolean equals(Object obj) {
830 if (this == obj) {
831 return true;
832 }
833 if (obj instanceof ExtensionInstructionWrapper) {
834 ExtensionInstructionWrapper that = (ExtensionInstructionWrapper) obj;
alshabib880b6442015-11-23 22:13:04 -0800835 return Objects.equals(extensionTreatment, that.extensionTreatment)
Jonathan Hart3c259162015-10-21 21:31:19 -0700836 && Objects.equals(deviceId, that.deviceId);
837
838 }
839 return false;
840 }
841 }
842
alshabib55a55d92014-09-16 11:59:31 -0700843}
alshabib8ca53902014-10-07 13:11:17 -0700844
845