blob: 621c0071e34c03a42941e844d15df32a5250c7a0 [file] [log] [blame]
Thomas Vachuska83e090e2014-10-22 14:25:35 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
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;
Cem Türker3baff672017-10-12 15:09:01 +030019import com.google.common.collect.ImmutableMap;
alshabib7b808c52015-06-26 14:22:24 -070020import org.onlab.packet.EthType;
Jonathan Hart54b406b2015-03-06 16:24:14 -080021import org.onlab.packet.IpAddress;
22import org.onlab.packet.MacAddress;
23import org.onlab.packet.MplsLabel;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -070024import org.onlab.packet.TpPort;
Jonathan Hart54b406b2015-03-06 16:24:14 -080025import org.onlab.packet.VlanId;
sangho8995ac52015-02-04 11:29:03 -080026import org.onosproject.core.GroupId;
Jonathan Hart3c259162015-10-21 21:31:19 -070027import org.onosproject.net.DeviceId;
Sho SHIMIZU2e7ac842015-05-05 15:45:38 -070028import 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;
Cem Türker3baff672017-10-12 15:09:01 +030032import org.onosproject.net.flow.StatTriggerField;
33import org.onosproject.net.flow.StatTriggerFlag;
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;
Frank Wangdf383212017-06-23 09:17:41 +080046import org.onosproject.net.pi.runtime.PiTableAction;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080047
Cem Türker3baff672017-10-12 15:09:01 +030048import java.util.Map;
Jonathan Hart54b406b2015-03-06 16:24:14 -080049import java.util.Objects;
50
51import static com.google.common.base.MoreObjects.toStringHelper;
52import static com.google.common.base.Preconditions.checkNotNull;
alshabib64231f62014-09-16 17:58:36 -070053
alshabib55a55d92014-09-16 11:59:31 -070054/**
55 * Factory class for creating various traffic treatment instructions.
56 */
57public final class Instructions {
58
Jonathan Hartc7840bd2016-01-21 23:26:29 -080059 private static final String SEPARATOR = ":";
60
alshabib55a55d92014-09-16 11:59:31 -070061 // Ban construction
62 private Instructions() {}
63
64 /**
65 * Creates an output instruction using the specified port number. This can
66 * include logical ports such as CONTROLLER, FLOOD, etc.
67 *
68 * @param number port number
69 * @return output instruction
70 */
71 public static OutputInstruction createOutput(final PortNumber number) {
72 checkNotNull(number, "PortNumber cannot be null");
73 return new OutputInstruction(number);
74 }
75
76 /**
Charles Chan7efabeb2015-09-28 15:12:19 -070077 * Creates a no action instruction.
78 *
79 * @return no action instruction
80 */
81 public static NoActionInstruction createNoAction() {
82 return new NoActionInstruction();
83 }
84
85 /**
sangho8995ac52015-02-04 11:29:03 -080086 * Creates a group instruction.
87 *
88 * @param groupId Group Id
89 * @return group instruction
90 */
91 public static GroupInstruction createGroup(final GroupId groupId) {
92 checkNotNull(groupId, "GroupId cannot be null");
93 return new GroupInstruction(groupId);
94 }
95
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +020096 /**
97 * Creates a set-queue instruction.
98 *
99 * @param queueId Queue Id
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200100 * @param port Port number
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200101 * @return set-queue instruction
102 */
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200103 public static SetQueueInstruction setQueue(final long queueId, final PortNumber port) {
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200104 return new SetQueueInstruction(queueId, port);
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200105 }
106
Jian Li1ef82db2016-03-03 14:43:21 -0800107 /**
108 * Creates a meter instruction.
109 *
110 * @param meterId Meter Id
111 * @return meter instruction
112 */
alshabib10c810b2015-08-18 16:59:04 -0700113 public static MeterInstruction meterTraffic(final MeterId meterId) {
114 checkNotNull(meterId, "meter id cannot be null");
115 return new MeterInstruction(meterId);
116 }
117
sangho8995ac52015-02-04 11:29:03 -0800118 /**
Sho SHIMIZUe9e12752015-05-05 14:45:40 -0700119 * Creates an L0 modification with the specified OCh signal.
120 *
121 * @param lambda OCh signal
122 * @return an L0 modification
123 */
Sho SHIMIZU2e7ac842015-05-05 15:45:38 -0700124 public static L0ModificationInstruction modL0Lambda(Lambda lambda) {
Sho SHIMIZUe9e12752015-05-05 14:45:40 -0700125 checkNotNull(lambda, "L0 OCh signal cannot be null");
Sho SHIMIZU2e7ac842015-05-05 15:45:38 -0700126
Sho SHIMIZUa114d892016-03-11 16:48:19 -0800127 if (lambda instanceof OchSignal) {
Sho SHIMIZU2e7ac842015-05-05 15:45:38 -0700128 return new ModOchSignalInstruction((OchSignal) lambda);
129 } else {
130 throw new UnsupportedOperationException(String.format("Unsupported type: %s", lambda));
131 }
Sho SHIMIZUe9e12752015-05-05 14:45:40 -0700132 }
133
134 /**
Yafit Hadar52d81552015-10-07 12:26:52 +0300135 * Creates an L1 modification with the specified ODU signal Id.
136 *
137 * @param oduSignalId ODU Signal Id
138 * @return a L1 modification
139 */
140 public static L1ModificationInstruction modL1OduSignalId(OduSignalId oduSignalId) {
141 checkNotNull(oduSignalId, "L1 ODU signal ID cannot be null");
142 return new ModOduSignalIdInstruction(oduSignalId);
143 }
144 /**
alshabib55a55d92014-09-16 11:59:31 -0700145 * Creates a l2 src modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800146 *
147 * @param addr the mac address to modify to
alshabib55a55d92014-09-16 11:59:31 -0700148 * @return a l2 modification
149 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700150 public static L2ModificationInstruction modL2Src(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -0700151 checkNotNull(addr, "Src l2 address cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700152 return new L2ModificationInstruction.ModEtherInstruction(
153 L2ModificationInstruction.L2SubType.ETH_SRC, addr);
alshabib55a55d92014-09-16 11:59:31 -0700154 }
155
156 /**
157 * Creates a L2 dst modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800158 *
159 * @param addr the mac address to modify to
alshabib55a55d92014-09-16 11:59:31 -0700160 * @return a L2 modification
161 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700162 public static L2ModificationInstruction modL2Dst(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -0700163 checkNotNull(addr, "Dst l2 address cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700164 return new L2ModificationInstruction.ModEtherInstruction(
165 L2ModificationInstruction.L2SubType.ETH_DST, addr);
alshabib55a55d92014-09-16 11:59:31 -0700166 }
167
168 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800169 * Creates a VLAN ID modification.
170 *
171 * @param vlanId the VLAN ID to modify to
alshabib7410fea2014-09-16 13:48:39 -0700172 * @return a L2 modification
173 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700174 public static L2ModificationInstruction modVlanId(VlanId vlanId) {
alshabib55a55d92014-09-16 11:59:31 -0700175 checkNotNull(vlanId, "VLAN id cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700176 return new L2ModificationInstruction.ModVlanIdInstruction(vlanId);
alshabib55a55d92014-09-16 11:59:31 -0700177 }
178
alshabib7410fea2014-09-16 13:48:39 -0700179 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800180 * Creates a VLAN PCP modification.
181 *
182 * @param vlanPcp the PCP to modify to
alshabib7410fea2014-09-16 13:48:39 -0700183 * @return a L2 modification
184 */
185 public static L2ModificationInstruction modVlanPcp(Byte vlanPcp) {
186 checkNotNull(vlanPcp, "VLAN Pcp cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700187 return new L2ModificationInstruction.ModVlanPcpInstruction(vlanPcp);
alshabib7410fea2014-09-16 13:48:39 -0700188 }
189
190 /**
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800191 * Creates a MPLS label modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800192 *
193 * @param mplsLabel MPLS label to set
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800194 * @return a L2 Modification
195 */
Michele Santuari4b6019e2014-12-19 11:31:45 +0100196 public static L2ModificationInstruction modMplsLabel(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800197 checkNotNull(mplsLabel, "MPLS label cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700198 return new L2ModificationInstruction.ModMplsLabelInstruction(mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800199 }
sangho3f97a17d2015-01-29 22:56:29 -0800200
201 /**
Saurav Das73a7dd42015-08-19 22:20:31 -0700202 * Creates a MPLS BOS bit modification.
203 *
204 * @param mplsBos MPLS BOS bit to set (true) or unset (false)
205 * @return a L2 Modification
206 */
207 public static L2ModificationInstruction modMplsBos(boolean mplsBos) {
208 return new L2ModificationInstruction.ModMplsBosInstruction(mplsBos);
209 }
210
211 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800212 * Creates a MPLS decrement TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800213 *
214 * @return a L2 Modification
215 */
216 public static L2ModificationInstruction decMplsTtl() {
alshabibd17abc22015-04-21 18:26:35 -0700217 return new L2ModificationInstruction.ModMplsTtlInstruction();
sangho3f97a17d2015-01-29 22:56:29 -0800218 }
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800219
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800220 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800221 * Creates a L3 IPv4 src modification.
222 *
223 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700224 * @return a L3 modification
225 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700226 public static L3ModificationInstruction modL3Src(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800227 checkNotNull(addr, "Src l3 IPv4 address cannot be null");
228 return new ModIPInstruction(L3SubType.IPV4_SRC, addr);
alshabib7410fea2014-09-16 13:48:39 -0700229 }
230
231 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800232 * Creates a L3 IPv4 dst modification.
233 *
234 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700235 * @return a L3 modification
236 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700237 public static L3ModificationInstruction modL3Dst(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800238 checkNotNull(addr, "Dst l3 IPv4 address cannot be null");
239 return new ModIPInstruction(L3SubType.IPV4_DST, addr);
240 }
241
242 /**
243 * Creates a L3 IPv6 src modification.
244 *
245 * @param addr the IPv6 address to modify to
246 * @return a L3 modification
247 */
248 public static L3ModificationInstruction modL3IPv6Src(IpAddress addr) {
249 checkNotNull(addr, "Src l3 IPv6 address cannot be null");
250 return new ModIPInstruction(L3SubType.IPV6_SRC, addr);
251 }
252
253 /**
254 * Creates a L3 IPv6 dst modification.
255 *
256 * @param addr the IPv6 address to modify to
257 * @return a L3 modification
258 */
259 public static L3ModificationInstruction modL3IPv6Dst(IpAddress addr) {
260 checkNotNull(addr, "Dst l3 IPv6 address cannot be null");
261 return new ModIPInstruction(L3SubType.IPV6_DST, addr);
262 }
263
264 /**
265 * Creates a L3 IPv6 Flow Label modification.
266 *
267 * @param flowLabel the IPv6 flow label to modify to (20 bits)
268 * @return a L3 modification
269 */
270 public static L3ModificationInstruction modL3IPv6FlowLabel(int flowLabel) {
271 return new ModIPv6FlowLabelInstruction(flowLabel);
alshabib7410fea2014-09-16 13:48:39 -0700272 }
273
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800274 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800275 * Creates a L3 decrement TTL modification.
276 *
sangho3f97a17d2015-01-29 22:56:29 -0800277 * @return a L3 modification
278 */
279 public static L3ModificationInstruction decNwTtl() {
280 return new ModTtlInstruction(L3SubType.DEC_TTL);
281 }
282
283 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800284 * Creates a L3 copy TTL to outer header modification.
285 *
sangho3f97a17d2015-01-29 22:56:29 -0800286 * @return a L3 modification
287 */
288 public static L3ModificationInstruction copyTtlOut() {
289 return new ModTtlInstruction(L3SubType.TTL_OUT);
290 }
291
292 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800293 * Creates a L3 copy TTL to inner header modification.
294 *
sangho3f97a17d2015-01-29 22:56:29 -0800295 * @return a L3 modification
296 */
297 public static L3ModificationInstruction copyTtlIn() {
298 return new ModTtlInstruction(L3SubType.TTL_IN);
299 }
300
301 /**
lishuai3cce60b2015-12-01 19:35:16 +0800302 * Creates a L3 ARP IP src modification.
303 *
304 * @param addr the ip address to modify to
305 * @return a L3 modification
306 */
307 public static L3ModificationInstruction modArpSpa(IpAddress addr) {
308 checkNotNull(addr, "Src l3 ARP IP address cannot be null");
309 return new ModArpIPInstruction(L3SubType.ARP_SPA, addr);
310 }
311
312 /**
313 * Creates a l3 ARP Ether src modification.
314 *
315 * @param addr the mac address to modify to
316 * @return a l3 modification
317 */
318 public static L3ModificationInstruction modArpSha(MacAddress addr) {
319 checkNotNull(addr, "Src l3 ARP address cannot be null");
320 return new ModArpEthInstruction(L3SubType.ARP_SHA, addr);
321 }
322
323 /**
souvikdas95c94223a2020-09-23 00:32:12 -0500324 * Creates a L3 ARP IP src modification.
325 *
326 * @param addr the ip address to modify to
327 * @return a L3 modification
328 */
329 public static L3ModificationInstruction modArpTpa(IpAddress addr) {
330 checkNotNull(addr, "Dst l3 ARP IP address cannot be null");
331 return new ModArpIPInstruction(L3SubType.ARP_TPA, addr);
332 }
333
334 /**
335 * Creates a l3 ARP Ether src modification.
336 *
337 * @param addr the mac address to modify to
338 * @return a l3 modification
339 */
340 public static L3ModificationInstruction modArpTha(MacAddress addr) {
341 checkNotNull(addr, "Dst l3 ARP address cannot be null");
342 return new ModArpEthInstruction(L3SubType.ARP_THA, addr);
343 }
344
345 /**
lishuai3cce60b2015-12-01 19:35:16 +0800346 * Creates a l3 ARP operation modification.
347 *
348 * @param op the ARP operation to modify to
349 * @return a l3 modification
350 */
351 public static L3ModificationInstruction modL3ArpOp(short op) {
lishuai3cce60b2015-12-01 19:35:16 +0800352 return new ModArpOpInstruction(L3SubType.ARP_OP, op);
353 }
354
355 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800356 * Creates a push MPLS header instruction.
357 *
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800358 * @return a L2 modification.
359 */
360 public static Instruction pushMpls() {
Jian Li11260a02016-05-19 13:07:22 -0700361 return new L2ModificationInstruction.ModMplsHeaderInstruction(
alshabibd17abc22015-04-21 18:26:35 -0700362 L2ModificationInstruction.L2SubType.MPLS_PUSH,
alshabib7b808c52015-06-26 14:22:24 -0700363 EthType.EtherType.MPLS_UNICAST.ethType());
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800364 }
365
366 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800367 * Creates a pop MPLS header instruction.
368 *
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800369 * @return a L2 modification.
370 */
371 public static Instruction popMpls() {
Jian Li11260a02016-05-19 13:07:22 -0700372 return new L2ModificationInstruction.ModMplsHeaderInstruction(
alshabibd17abc22015-04-21 18:26:35 -0700373 L2ModificationInstruction.L2SubType.MPLS_POP,
alshabib7b808c52015-06-26 14:22:24 -0700374 EthType.EtherType.MPLS_UNICAST.ethType());
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800375 }
alshabib7410fea2014-09-16 13:48:39 -0700376
sangho3f97a17d2015-01-29 22:56:29 -0800377 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800378 * Creates a pop MPLS header instruction with a particular ethertype.
sangho3f97a17d2015-01-29 22:56:29 -0800379 *
380 * @param etherType Ethernet type to set
381 * @return a L2 modification.
alshabib7b808c52015-06-26 14:22:24 -0700382 */
383 public static Instruction popMpls(EthType etherType) {
384 checkNotNull(etherType, "Ethernet type cannot be null");
Jian Li11260a02016-05-19 13:07:22 -0700385 return new L2ModificationInstruction.ModMplsHeaderInstruction(
alshabibd17abc22015-04-21 18:26:35 -0700386 L2ModificationInstruction.L2SubType.MPLS_POP, etherType);
sangho3f97a17d2015-01-29 22:56:29 -0800387 }
388
Saurav Dasfbe25c52015-03-04 11:12:00 -0800389 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800390 * Creates a pop VLAN header instruction.
391 *
392 * @return a L2 modification
Saurav Dasfbe25c52015-03-04 11:12:00 -0800393 */
394 public static Instruction popVlan() {
Jian Li11260a02016-05-19 13:07:22 -0700395 return new L2ModificationInstruction.ModVlanHeaderInstruction(
alshabibd17abc22015-04-21 18:26:35 -0700396 L2ModificationInstruction.L2SubType.VLAN_POP);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800397 }
398
399 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800400 * Creates a push VLAN header instruction.
401 *
402 * @return a L2 modification
403 */
404 public static Instruction pushVlan() {
Jian Li11260a02016-05-19 13:07:22 -0700405 return new L2ModificationInstruction.ModVlanHeaderInstruction(
alshabib7b808c52015-06-26 14:22:24 -0700406 L2ModificationInstruction.L2SubType.VLAN_PUSH,
407 EthType.EtherType.VLAN.ethType());
Jonathan Hart54b406b2015-03-06 16:24:14 -0800408 }
409
410 /**
Konstantinos Kanonakis9215ff22016-11-04 13:28:11 -0500411 * Creates a push VLAN header instruction using the supplied Ethernet type.
412 *
413 * @param ethType the Ethernet type to use
414 * @return a L2 modification
415 */
416 public static Instruction pushVlan(EthType ethType) {
417 return new L2ModificationInstruction.ModVlanHeaderInstruction(
418 L2ModificationInstruction.L2SubType.VLAN_PUSH,
419 ethType);
420 }
421
422 /**
alshabibd17abc22015-04-21 18:26:35 -0700423 * Sends the packet to the table id.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800424 *
alshabibd17abc22015-04-21 18:26:35 -0700425 * @param tableId flow rule table id
Thomas Vachuska3e2b6512015-03-05 09:25:03 -0800426 * @return table type transition instruction
Saurav Dasfbe25c52015-03-04 11:12:00 -0800427 */
alshabibd17abc22015-04-21 18:26:35 -0700428 public static Instruction transition(Integer tableId) {
429 checkNotNull(tableId, "Table id cannot be null");
430 return new TableTypeTransition(tableId);
alshabib9af70072015-02-09 14:34:16 -0800431 }
432
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800433 /**
Saurav Das86af8f12015-05-25 23:55:33 -0700434 * Writes metadata to associate with a packet.
435 *
436 * @param metadata the metadata value to write
437 * @param metadataMask the bits to mask for the metadata value
438 * @return metadata instruction
439 */
440 public static Instruction writeMetadata(long metadata, long metadataMask) {
441 return new MetadataInstruction(metadata, metadataMask);
442 }
443
444 /**
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700445 * Creates a Tunnel ID modification.
446 *
447 * @param tunnelId the Tunnel ID to modify to
448 * @return a L2 modification
449 */
450 public static L2ModificationInstruction modTunnelId(long tunnelId) {
Hyunsun Moona08c5d02015-07-14 17:53:00 -0700451 return new L2ModificationInstruction.ModTunnelIdInstruction(tunnelId);
452 }
453
454 /**
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700455 * Creates a TCP src modification.
456 *
457 * @param port the TCP port number to modify to
458 * @return a L4 modification
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700459 */
460 public static L4ModificationInstruction modTcpSrc(TpPort port) {
461 checkNotNull(port, "Src TCP port cannot be null");
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700462 return new ModTransportPortInstruction(L4SubType.TCP_SRC, port);
463 }
464
465 /**
466 * Creates a TCP dst modification.
467 *
468 * @param port the TCP port number to modify to
469 * @return a L4 modification
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700470 */
471 public static L4ModificationInstruction modTcpDst(TpPort port) {
472 checkNotNull(port, "Dst TCP port cannot be null");
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700473 return new ModTransportPortInstruction(L4SubType.TCP_DST, port);
474 }
475
476 /**
477 * Creates a UDP src modification.
478 *
479 * @param port the UDP port number to modify to
480 * @return a L4 modification
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700481 */
482 public static L4ModificationInstruction modUdpSrc(TpPort port) {
483 checkNotNull(port, "Src UDP port cannot be null");
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700484 return new ModTransportPortInstruction(L4SubType.UDP_SRC, port);
485 }
486
487 /**
488 * Creates a UDP dst modification.
489 *
490 * @param port the UDP port number to modify to
491 * @return a L4 modification
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700492 */
493 public static L4ModificationInstruction modUdpDst(TpPort port) {
494 checkNotNull(port, "Dst UDP port cannot be null");
Hyunsun Moonc8bd97c2015-07-18 22:47:33 -0700495 return new ModTransportPortInstruction(L4SubType.UDP_DST, port);
496 }
497
498 /**
Frank Wangdf383212017-06-23 09:17:41 +0800499 * Creates a protocol independent instruction.
500 *
501 * @param piTableAction protocol independent instruction
502 * @return extension instruction
503 */
504 public static PiInstruction piTableAction(PiTableAction piTableAction) {
505 checkNotNull(piTableAction, "PiTableAction instruction cannot be null");
506 return new PiInstruction(piTableAction);
507 }
508
509 /**
Thiago Santos4a69ef82018-08-21 21:18:05 -0700510 * Creates an IP DSCP modification.
511 *
Rory Savagedaeb9492020-02-18 14:35:50 -0500512 * @param ipDscp the DSCP value to modify to
Thiago Santos4a69ef82018-08-21 21:18:05 -0700513 * @return a L3 modification
514 */
Rory Savagedaeb9492020-02-18 14:35:50 -0500515 public static Instruction modIpDscp(byte ipDscp) {
516 return new L3ModificationInstruction.ModDscpInstruction(L3SubType.IP_DSCP, ipDscp);
Thiago Santos4a69ef82018-08-21 21:18:05 -0700517 }
518
519 /**
Jonathan Hart3c259162015-10-21 21:31:19 -0700520 * Creates an extension instruction.
521 *
522 * @param extension extension instruction
523 * @param deviceId device ID
524 * @return extension instruction
525 */
alshabib880b6442015-11-23 22:13:04 -0800526 public static ExtensionInstructionWrapper extension(ExtensionTreatment extension,
Jonathan Hart3c259162015-10-21 21:31:19 -0700527 DeviceId deviceId) {
528 checkNotNull(extension, "Extension instruction cannot be null");
529 checkNotNull(deviceId, "Device ID cannot be null");
530 return new ExtensionInstructionWrapper(extension, deviceId);
531 }
532
533 /**
Cem Türker3baff672017-10-12 15:09:01 +0300534 * Creates a stat trigger instruction.
535 *
536 * @param statTriggerMap map keeps stat trigger threshold
537 * @param flag stat trigger flag
538 * @return stat trigger instruction
539 */
540 public static StatTriggerInstruction statTrigger(Map<StatTriggerField, Long> statTriggerMap,
541 StatTriggerFlag flag) {
542 checkNotNull(statTriggerMap, "Stat trigger map cannot be null");
543 checkNotNull(flag, "Stat trigger flag cannot be null");
544 return new StatTriggerInstruction(statTriggerMap, flag);
545 }
546
547 /**
Charles Chan7efabeb2015-09-28 15:12:19 -0700548 * No Action instruction.
549 */
550 public static final class NoActionInstruction implements Instruction {
551
552 private NoActionInstruction() {}
553
554 @Override
555 public Type type() {
556 return Type.NOACTION;
557 }
558
559 @Override
560 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800561 return type().toString();
Charles Chan7efabeb2015-09-28 15:12:19 -0700562 }
563
564 @Override
565 public int hashCode() {
HIGUCHI Yutaca9cc8e2015-10-29 23:26:51 -0700566 return type().ordinal();
Charles Chan7efabeb2015-09-28 15:12:19 -0700567 }
568
569 @Override
570 public boolean equals(Object obj) {
571 if (this == obj) {
572 return true;
573 }
574 if (obj instanceof NoActionInstruction) {
575 return true;
576 }
577 return false;
578 }
579 }
580
581 /**
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800582 * Output Instruction.
sangho8995ac52015-02-04 11:29:03 -0800583 */
alshabib55a55d92014-09-16 11:59:31 -0700584 public static final class OutputInstruction implements Instruction {
585 private final PortNumber port;
586
587 private OutputInstruction(PortNumber port) {
588 this.port = port;
589 }
590
591 public PortNumber port() {
592 return port;
593 }
594
595 @Override
596 public Type type() {
597 return Type.OUTPUT;
598 }
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800599
alshabib99b8fdc2014-09-25 14:30:22 -0700600 @Override
601 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800602 return type().toString() + SEPARATOR + port.toString();
alshabib99b8fdc2014-09-25 14:30:22 -0700603 }
alshabib8ca53902014-10-07 13:11:17 -0700604
605 @Override
606 public int hashCode() {
Thomas Vachuska6c8eff32015-05-27 16:11:44 -0700607 return Objects.hash(type().ordinal(), port);
alshabib8ca53902014-10-07 13:11:17 -0700608 }
609
610 @Override
611 public boolean equals(Object obj) {
612 if (this == obj) {
613 return true;
614 }
615 if (obj instanceof OutputInstruction) {
616 OutputInstruction that = (OutputInstruction) obj;
Yuta HIGUCHI4ce65292014-11-01 12:09:55 -0700617 return Objects.equals(port, that.port);
alshabib8ca53902014-10-07 13:11:17 -0700618
619 }
620 return false;
621 }
alshabib55a55d92014-09-16 11:59:31 -0700622 }
623
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800624 /**
625 * Group Instruction.
sangho8995ac52015-02-04 11:29:03 -0800626 */
sangho8995ac52015-02-04 11:29:03 -0800627 public static final class GroupInstruction implements Instruction {
628 private final GroupId groupId;
629
630 private GroupInstruction(GroupId groupId) {
631 this.groupId = groupId;
632 }
633
634 public GroupId groupId() {
635 return groupId;
636 }
637
638 @Override
639 public Type type() {
640 return Type.GROUP;
641 }
alshabib9af70072015-02-09 14:34:16 -0800642
sangho8995ac52015-02-04 11:29:03 -0800643 @Override
644 public String toString() {
Saurav Das0fd79d92016-03-07 10:58:36 -0800645 return type().toString() + SEPARATOR + "0x" + Integer.toHexString(groupId.id());
sangho8995ac52015-02-04 11:29:03 -0800646 }
647
648 @Override
649 public int hashCode() {
Thomas Vachuska6c8eff32015-05-27 16:11:44 -0700650 return Objects.hash(type().ordinal(), groupId);
sangho8995ac52015-02-04 11:29:03 -0800651 }
652
653 @Override
654 public boolean equals(Object obj) {
655 if (this == obj) {
656 return true;
657 }
658 if (obj instanceof GroupInstruction) {
659 GroupInstruction that = (GroupInstruction) obj;
660 return Objects.equals(groupId, that.groupId);
661
662 }
663 return false;
664 }
665 }
666
Saurav Das86af8f12015-05-25 23:55:33 -0700667 /**
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200668 * Set-Queue Instruction.
669 */
670 public static final class SetQueueInstruction implements Instruction {
671 private final long queueId;
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200672 private final PortNumber port;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200673
674 private SetQueueInstruction(long queueId) {
675 this.queueId = queueId;
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200676 this.port = null;
677 }
678
679 private SetQueueInstruction(long queueId, PortNumber port) {
680 this.queueId = queueId;
681 this.port = port;
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200682 }
683
684 public long queueId() {
685 return queueId;
686 }
687
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200688 public PortNumber port() {
689 return port;
690 }
691
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200692 @Override
693 public Type type() {
694 return Type.QUEUE;
695 }
696
697 @Override
698 public String toString() {
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200699 MoreObjects.ToStringHelper toStringHelper = toStringHelper(type().toString());
700 toStringHelper.add("queueId", queueId);
701
702 if (port() != null) {
703 toStringHelper.add("port", port);
704 }
705 return toStringHelper.toString();
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200706 }
707
708 @Override
709 public int hashCode() {
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200710 return Objects.hash(type().ordinal(), queueId, port);
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200711 }
712
713 @Override
714 public boolean equals(Object obj) {
715 if (this == obj) {
716 return true;
717 }
718 if (obj instanceof SetQueueInstruction) {
719 SetQueueInstruction that = (SetQueueInstruction) obj;
Steffen Gebertba2d3b72015-10-22 11:14:31 +0200720 return Objects.equals(queueId, that.queueId) && Objects.equals(port, that.port);
Steffen Gebertbbfdaaa2015-09-29 11:01:46 +0200721
722 }
723 return false;
724 }
725 }
726
727 /**
alshabib10c810b2015-08-18 16:59:04 -0700728 * A meter instruction.
729 */
730 public static final class MeterInstruction implements Instruction {
731 private final MeterId meterId;
732
733 private MeterInstruction(MeterId meterId) {
734 this.meterId = meterId;
735 }
736
737 public MeterId meterId() {
738 return meterId;
739 }
740
741 @Override
742 public Type type() {
743 return Type.METER;
744 }
745
746 @Override
747 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800748 return type().toString() + SEPARATOR + meterId.id();
alshabib10c810b2015-08-18 16:59:04 -0700749 }
750
751 @Override
752 public int hashCode() {
753 return Objects.hash(type().ordinal(), meterId);
754 }
755
756 @Override
757 public boolean equals(Object obj) {
758 if (this == obj) {
759 return true;
760 }
761 if (obj instanceof MeterInstruction) {
762 MeterInstruction that = (MeterInstruction) obj;
763 return Objects.equals(meterId, that.meterId);
764
765 }
766 return false;
767 }
768 }
769
770 /**
Saurav Das86af8f12015-05-25 23:55:33 -0700771 * Transition instruction.
772 */
alshabibd17abc22015-04-21 18:26:35 -0700773 public static class TableTypeTransition implements Instruction {
774 private final Integer tableId;
775
776 TableTypeTransition(Integer tableId) {
777 this.tableId = tableId;
alshabib9af70072015-02-09 14:34:16 -0800778 }
779
780 @Override
781 public Type type() {
782 return Type.TABLE;
783 }
784
alshabibd17abc22015-04-21 18:26:35 -0700785 public Integer tableId() {
786 return this.tableId;
alshabib9af70072015-02-09 14:34:16 -0800787 }
788
789 @Override
790 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800791 return type().toString() + SEPARATOR + this.tableId;
alshabib9af70072015-02-09 14:34:16 -0800792 }
793
794 @Override
795 public int hashCode() {
Thomas Vachuska6c8eff32015-05-27 16:11:44 -0700796 return Objects.hash(type().ordinal(), tableId);
alshabib9af70072015-02-09 14:34:16 -0800797 }
798
799 @Override
800 public boolean equals(Object obj) {
801 if (this == obj) {
802 return true;
803 }
804 if (obj instanceof TableTypeTransition) {
805 TableTypeTransition that = (TableTypeTransition) obj;
alshabibd17abc22015-04-21 18:26:35 -0700806 return Objects.equals(tableId, that.tableId);
alshabib9af70072015-02-09 14:34:16 -0800807
808 }
809 return false;
810 }
Saurav Das86af8f12015-05-25 23:55:33 -0700811 }
alshabib9af70072015-02-09 14:34:16 -0800812
Saurav Das86af8f12015-05-25 23:55:33 -0700813 /**
814 * Metadata instruction.
815 */
816 public static class MetadataInstruction implements Instruction {
817 private final long metadata;
818 private final long metadataMask;
819
820 MetadataInstruction(long metadata, long metadataMask) {
821 this.metadata = metadata;
822 this.metadataMask = metadataMask;
823 }
824
825 @Override
826 public Type type() {
827 return Type.METADATA;
828 }
829
830 public long metadata() {
831 return this.metadata;
832 }
833
834 public long metadataMask() {
835 return this.metadataMask;
836 }
837
838 @Override
839 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800840 return type().toString() + SEPARATOR +
841 Long.toHexString(this.metadata) + "/" +
842 Long.toHexString(this.metadataMask);
Saurav Das86af8f12015-05-25 23:55:33 -0700843 }
844
845 @Override
846 public int hashCode() {
Thomas Vachuska6c8eff32015-05-27 16:11:44 -0700847 return Objects.hash(type().ordinal(), metadata, metadataMask);
Saurav Das86af8f12015-05-25 23:55:33 -0700848 }
849
850 @Override
851 public boolean equals(Object obj) {
852 if (this == obj) {
853 return true;
854 }
855 if (obj instanceof MetadataInstruction) {
856 MetadataInstruction that = (MetadataInstruction) obj;
857 return Objects.equals(metadata, that.metadata) &&
858 Objects.equals(metadataMask, that.metadataMask);
859
860 }
861 return false;
862 }
alshabib9af70072015-02-09 14:34:16 -0800863 }
Saurav Das73a7dd42015-08-19 22:20:31 -0700864
Jonathan Hart3c259162015-10-21 21:31:19 -0700865 /**
866 * Extension instruction.
867 */
868 public static class ExtensionInstructionWrapper implements Instruction {
alshabib880b6442015-11-23 22:13:04 -0800869 private final ExtensionTreatment extensionTreatment;
Jonathan Hart3c259162015-10-21 21:31:19 -0700870 private final DeviceId deviceId;
871
alshabib880b6442015-11-23 22:13:04 -0800872 ExtensionInstructionWrapper(ExtensionTreatment extension, DeviceId deviceId) {
873 extensionTreatment = extension;
Jonathan Hart3c259162015-10-21 21:31:19 -0700874 this.deviceId = deviceId;
875 }
876
alshabib880b6442015-11-23 22:13:04 -0800877 public ExtensionTreatment extensionInstruction() {
878 return extensionTreatment;
Jonathan Hart3c259162015-10-21 21:31:19 -0700879 }
880
881 public DeviceId deviceId() {
882 return deviceId;
883 }
884
885 @Override
886 public Type type() {
887 return Type.EXTENSION;
888 }
889
890 @Override
891 public String toString() {
Jonathan Hartc7840bd2016-01-21 23:26:29 -0800892 return type().toString() + SEPARATOR + deviceId + "/" + extensionTreatment;
Jonathan Hart3c259162015-10-21 21:31:19 -0700893 }
894
895 @Override
896 public int hashCode() {
alshabib880b6442015-11-23 22:13:04 -0800897 return Objects.hash(type().ordinal(), extensionTreatment, deviceId);
Jonathan Hart3c259162015-10-21 21:31:19 -0700898 }
899
900 @Override
901 public boolean equals(Object obj) {
902 if (this == obj) {
903 return true;
904 }
905 if (obj instanceof ExtensionInstructionWrapper) {
906 ExtensionInstructionWrapper that = (ExtensionInstructionWrapper) obj;
alshabib880b6442015-11-23 22:13:04 -0800907 return Objects.equals(extensionTreatment, that.extensionTreatment)
Jonathan Hart3c259162015-10-21 21:31:19 -0700908 && Objects.equals(deviceId, that.deviceId);
909
910 }
911 return false;
912 }
913 }
914
Cem Türker3baff672017-10-12 15:09:01 +0300915 public static class StatTriggerInstruction implements Instruction {
916 private Map<StatTriggerField, Long> statTriggerFieldMap;
917 private StatTriggerFlag statTriggerFlag;
918
919
920 StatTriggerInstruction(Map<StatTriggerField, Long> statTriggerMap,
921 StatTriggerFlag flag) {
922 this.statTriggerFieldMap = ImmutableMap.copyOf(statTriggerMap);
923 this.statTriggerFlag = flag;
924 }
925
926 public Map<StatTriggerField, Long> getStatTriggerFieldMap() {
927 return statTriggerFieldMap;
928 }
929
930 public StatTriggerFlag getStatTriggerFlag() {
931 return statTriggerFlag;
932 }
933
934 public Long getStatValue(StatTriggerField field) {
935 return statTriggerFieldMap.get(field);
936 }
937
938 @Override
939 public Type type() {
940 return Type.STAT_TRIGGER;
941 }
942
943 @Override
944 public String toString() {
945 return "StatTriggerInstruction{" +
946 "statTriggerFieldMap=" + statTriggerFieldMap +
947 ", statTriggerFlag=" + statTriggerFlag +
948 '}';
949 }
950
951 @Override
952 public boolean equals(Object o) {
953 if (this == o) {
954 return true;
955 }
956 if (o == null || getClass() != o.getClass()) {
957 return false;
958 }
959
960 StatTriggerInstruction that = (StatTriggerInstruction) o;
961
962 if (!Objects.equals(statTriggerFieldMap, that.statTriggerFieldMap)) {
963 return false;
964 }
965
966 return statTriggerFlag == that.statTriggerFlag;
967 }
968
969 @Override
970 public int hashCode() {
971 int result = statTriggerFieldMap != null ? statTriggerFieldMap.hashCode() : 0;
972 result = 31 * result + (statTriggerFlag != null ? statTriggerFlag.hashCode() : 0);
973 return result;
974 }
975 }
976
alshabib55a55d92014-09-16 11:59:31 -0700977}
alshabib8ca53902014-10-07 13:11:17 -0700978
979