blob: 03588b826c7460acb2fd95916e83652c8754a3c1 [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
Jonathan Hart54b406b2015-03-06 16:24:14 -080018import org.onlab.packet.Ethernet;
19import org.onlab.packet.IpAddress;
20import org.onlab.packet.MacAddress;
21import org.onlab.packet.MplsLabel;
22import org.onlab.packet.VlanId;
sangho8995ac52015-02-04 11:29:03 -080023import org.onosproject.core.GroupId;
Brian O'Connorabafb502014-12-02 22:26:20 -080024import org.onosproject.net.PortNumber;
25import org.onosproject.net.flow.instructions.L0ModificationInstruction.L0SubType;
26import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080027import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType;
28import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080029import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
sangho3f97a17d2015-01-29 22:56:29 -080030import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080031
Jonathan Hart54b406b2015-03-06 16:24:14 -080032import java.util.Objects;
33
34import static com.google.common.base.MoreObjects.toStringHelper;
35import static com.google.common.base.Preconditions.checkNotNull;
alshabib64231f62014-09-16 17:58:36 -070036
alshabib55a55d92014-09-16 11:59:31 -070037/**
38 * Factory class for creating various traffic treatment instructions.
39 */
40public final class Instructions {
41
42
43 // Ban construction
44 private Instructions() {}
45
46 /**
47 * Creates an output instruction using the specified port number. This can
48 * include logical ports such as CONTROLLER, FLOOD, etc.
49 *
50 * @param number port number
51 * @return output instruction
52 */
53 public static OutputInstruction createOutput(final PortNumber number) {
54 checkNotNull(number, "PortNumber cannot be null");
55 return new OutputInstruction(number);
56 }
57
58 /**
59 * Creates a drop instruction.
Jonathan Hart54b406b2015-03-06 16:24:14 -080060 *
alshabib55a55d92014-09-16 11:59:31 -070061 * @return drop instruction
62 */
63 public static DropInstruction createDrop() {
64 return new DropInstruction();
65 }
66
67 /**
sangho8995ac52015-02-04 11:29:03 -080068 * Creates a group instruction.
69 *
70 * @param groupId Group Id
71 * @return group instruction
72 */
73 public static GroupInstruction createGroup(final GroupId groupId) {
74 checkNotNull(groupId, "GroupId cannot be null");
75 return new GroupInstruction(groupId);
76 }
77
78 /**
Marc De Leenheer49087752014-10-23 13:54:09 -070079 * Creates a l0 modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -080080 *
81 * @param lambda the lambda to modify to
Marc De Leenheer49087752014-10-23 13:54:09 -070082 * @return a l0 modification
83 */
84 public static L0ModificationInstruction modL0Lambda(short lambda) {
85 checkNotNull(lambda, "L0 lambda cannot be null");
86 return new ModLambdaInstruction(L0SubType.LAMBDA, lambda);
87 }
88
89 /**
alshabib55a55d92014-09-16 11:59:31 -070090 * Creates a l2 src modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -080091 *
92 * @param addr the mac address to modify to
alshabib55a55d92014-09-16 11:59:31 -070093 * @return a l2 modification
94 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -070095 public static L2ModificationInstruction modL2Src(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -070096 checkNotNull(addr, "Src l2 address cannot be null");
alshabibd17abc22015-04-21 18:26:35 -070097 return new L2ModificationInstruction.ModEtherInstruction(
98 L2ModificationInstruction.L2SubType.ETH_SRC, addr);
alshabib55a55d92014-09-16 11:59:31 -070099 }
100
101 /**
102 * Creates a L2 dst modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800103 *
104 * @param addr the mac address to modify to
alshabib55a55d92014-09-16 11:59:31 -0700105 * @return a L2 modification
106 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700107 public static L2ModificationInstruction modL2Dst(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -0700108 checkNotNull(addr, "Dst l2 address cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700109 return new L2ModificationInstruction.ModEtherInstruction(
110 L2ModificationInstruction.L2SubType.ETH_DST, addr);
alshabib55a55d92014-09-16 11:59:31 -0700111 }
112
113 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800114 * Creates a VLAN ID modification.
115 *
116 * @param vlanId the VLAN ID to modify to
alshabib7410fea2014-09-16 13:48:39 -0700117 * @return a L2 modification
118 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700119 public static L2ModificationInstruction modVlanId(VlanId vlanId) {
alshabib55a55d92014-09-16 11:59:31 -0700120 checkNotNull(vlanId, "VLAN id cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700121 return new L2ModificationInstruction.ModVlanIdInstruction(vlanId);
alshabib55a55d92014-09-16 11:59:31 -0700122 }
123
alshabib7410fea2014-09-16 13:48:39 -0700124 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800125 * Creates a VLAN PCP modification.
126 *
127 * @param vlanPcp the PCP to modify to
alshabib7410fea2014-09-16 13:48:39 -0700128 * @return a L2 modification
129 */
130 public static L2ModificationInstruction modVlanPcp(Byte vlanPcp) {
131 checkNotNull(vlanPcp, "VLAN Pcp cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700132 return new L2ModificationInstruction.ModVlanPcpInstruction(vlanPcp);
alshabib7410fea2014-09-16 13:48:39 -0700133 }
134
135 /**
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800136 * Creates a MPLS label modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800137 *
138 * @param mplsLabel MPLS label to set
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800139 * @return a L2 Modification
140 */
Michele Santuari4b6019e2014-12-19 11:31:45 +0100141 public static L2ModificationInstruction modMplsLabel(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800142 checkNotNull(mplsLabel, "MPLS label cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700143 return new L2ModificationInstruction.ModMplsLabelInstruction(mplsLabel);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800144 }
sangho3f97a17d2015-01-29 22:56:29 -0800145
146 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800147 * Creates a MPLS decrement TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800148 *
149 * @return a L2 Modification
150 */
151 public static L2ModificationInstruction decMplsTtl() {
alshabibd17abc22015-04-21 18:26:35 -0700152 return new L2ModificationInstruction.ModMplsTtlInstruction();
sangho3f97a17d2015-01-29 22:56:29 -0800153 }
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800154
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800155 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800156 * Creates a L3 IPv4 src modification.
157 *
158 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700159 * @return a L3 modification
160 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700161 public static L3ModificationInstruction modL3Src(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800162 checkNotNull(addr, "Src l3 IPv4 address cannot be null");
163 return new ModIPInstruction(L3SubType.IPV4_SRC, addr);
alshabib7410fea2014-09-16 13:48:39 -0700164 }
165
166 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800167 * Creates a L3 IPv4 dst modification.
168 *
169 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700170 * @return a L3 modification
171 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700172 public static L3ModificationInstruction modL3Dst(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800173 checkNotNull(addr, "Dst l3 IPv4 address cannot be null");
174 return new ModIPInstruction(L3SubType.IPV4_DST, addr);
175 }
176
177 /**
178 * Creates a L3 IPv6 src modification.
179 *
180 * @param addr the IPv6 address to modify to
181 * @return a L3 modification
182 */
183 public static L3ModificationInstruction modL3IPv6Src(IpAddress addr) {
184 checkNotNull(addr, "Src l3 IPv6 address cannot be null");
185 return new ModIPInstruction(L3SubType.IPV6_SRC, addr);
186 }
187
188 /**
189 * Creates a L3 IPv6 dst modification.
190 *
191 * @param addr the IPv6 address to modify to
192 * @return a L3 modification
193 */
194 public static L3ModificationInstruction modL3IPv6Dst(IpAddress addr) {
195 checkNotNull(addr, "Dst l3 IPv6 address cannot be null");
196 return new ModIPInstruction(L3SubType.IPV6_DST, addr);
197 }
198
199 /**
200 * Creates a L3 IPv6 Flow Label modification.
201 *
202 * @param flowLabel the IPv6 flow label to modify to (20 bits)
203 * @return a L3 modification
204 */
205 public static L3ModificationInstruction modL3IPv6FlowLabel(int flowLabel) {
206 return new ModIPv6FlowLabelInstruction(flowLabel);
alshabib7410fea2014-09-16 13:48:39 -0700207 }
208
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800209 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800210 * Creates a L3 decrement TTL modification.
211 *
sangho3f97a17d2015-01-29 22:56:29 -0800212 * @return a L3 modification
213 */
214 public static L3ModificationInstruction decNwTtl() {
215 return new ModTtlInstruction(L3SubType.DEC_TTL);
216 }
217
218 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800219 * Creates a L3 copy TTL to outer header modification.
220 *
sangho3f97a17d2015-01-29 22:56:29 -0800221 * @return a L3 modification
222 */
223 public static L3ModificationInstruction copyTtlOut() {
224 return new ModTtlInstruction(L3SubType.TTL_OUT);
225 }
226
227 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800228 * Creates a L3 copy TTL to inner header modification.
229 *
sangho3f97a17d2015-01-29 22:56:29 -0800230 * @return a L3 modification
231 */
232 public static L3ModificationInstruction copyTtlIn() {
233 return new ModTtlInstruction(L3SubType.TTL_IN);
234 }
235
236 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800237 * Creates a push MPLS header instruction.
238 *
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800239 * @return a L2 modification.
240 */
241 public static Instruction pushMpls() {
alshabibd17abc22015-04-21 18:26:35 -0700242 return new L2ModificationInstruction.PushHeaderInstructions(
243 L2ModificationInstruction.L2SubType.MPLS_PUSH,
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800244 Ethernet.MPLS_UNICAST);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800245 }
246
247 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800248 * Creates a pop MPLS header instruction.
249 *
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800250 * @return a L2 modification.
251 */
252 public static Instruction popMpls() {
alshabibd17abc22015-04-21 18:26:35 -0700253 return new L2ModificationInstruction.PushHeaderInstructions(
254 L2ModificationInstruction.L2SubType.MPLS_POP,
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800255 Ethernet.MPLS_UNICAST);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800256 }
alshabib7410fea2014-09-16 13:48:39 -0700257
sangho3f97a17d2015-01-29 22:56:29 -0800258 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800259 * Creates a pop MPLS header instruction with a particular ethertype.
sangho3f97a17d2015-01-29 22:56:29 -0800260 *
261 * @param etherType Ethernet type to set
262 * @return a L2 modification.
263 */
264 public static Instruction popMpls(Short etherType) {
265 checkNotNull(etherType, "Ethernet type cannot be null");
alshabibd17abc22015-04-21 18:26:35 -0700266 return new L2ModificationInstruction.PushHeaderInstructions(
267 L2ModificationInstruction.L2SubType.MPLS_POP, etherType);
sangho3f97a17d2015-01-29 22:56:29 -0800268 }
269
Saurav Dasfbe25c52015-03-04 11:12:00 -0800270 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800271 * Creates a pop VLAN header instruction.
272 *
273 * @return a L2 modification
Saurav Dasfbe25c52015-03-04 11:12:00 -0800274 */
275 public static Instruction popVlan() {
alshabibd17abc22015-04-21 18:26:35 -0700276 return new L2ModificationInstruction.PopVlanInstruction(
277 L2ModificationInstruction.L2SubType.VLAN_POP);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800278 }
279
280 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800281 * Creates a push VLAN header instruction.
282 *
283 * @return a L2 modification
284 */
285 public static Instruction pushVlan() {
alshabibd17abc22015-04-21 18:26:35 -0700286 return new L2ModificationInstruction.PushHeaderInstructions(
287 L2ModificationInstruction.L2SubType.VLAN_PUSH, Ethernet.TYPE_VLAN);
Jonathan Hart54b406b2015-03-06 16:24:14 -0800288 }
289
290 /**
alshabibd17abc22015-04-21 18:26:35 -0700291 * Sends the packet to the table id.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800292 *
alshabibd17abc22015-04-21 18:26:35 -0700293 * @param tableId flow rule table id
Thomas Vachuska3e2b6512015-03-05 09:25:03 -0800294 * @return table type transition instruction
Saurav Dasfbe25c52015-03-04 11:12:00 -0800295 */
alshabibd17abc22015-04-21 18:26:35 -0700296 public static Instruction transition(Integer tableId) {
297 checkNotNull(tableId, "Table id cannot be null");
298 return new TableTypeTransition(tableId);
alshabib9af70072015-02-09 14:34:16 -0800299 }
300
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800301 /**
302 * Drop instruction.
alshabib55a55d92014-09-16 11:59:31 -0700303 */
alshabib55a55d92014-09-16 11:59:31 -0700304 public static final class DropInstruction implements Instruction {
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800305
306 private DropInstruction() {}
307
alshabib55a55d92014-09-16 11:59:31 -0700308 @Override
309 public Type type() {
310 return Type.DROP;
311 }
alshabib99b8fdc2014-09-25 14:30:22 -0700312
313 @Override
314 public String toString() {
alshabib346b5b32015-03-06 00:42:16 -0800315 return toStringHelper(type().toString()).toString();
alshabib99b8fdc2014-09-25 14:30:22 -0700316 }
alshabib8ca53902014-10-07 13:11:17 -0700317
318 @Override
319 public int hashCode() {
320 return Objects.hash(type());
321 }
322
323 @Override
324 public boolean equals(Object obj) {
325 if (this == obj) {
326 return true;
327 }
328 if (obj instanceof DropInstruction) {
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800329 return true;
alshabib8ca53902014-10-07 13:11:17 -0700330 }
331 return false;
332 }
alshabib55a55d92014-09-16 11:59:31 -0700333 }
334
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800335 /**
336 * Output Instruction.
sangho8995ac52015-02-04 11:29:03 -0800337 */
alshabib55a55d92014-09-16 11:59:31 -0700338 public static final class OutputInstruction implements Instruction {
339 private final PortNumber port;
340
341 private OutputInstruction(PortNumber port) {
342 this.port = port;
343 }
344
345 public PortNumber port() {
346 return port;
347 }
348
349 @Override
350 public Type type() {
351 return Type.OUTPUT;
352 }
alshabib99b8fdc2014-09-25 14:30:22 -0700353 @Override
354 public String toString() {
355 return toStringHelper(type().toString())
356 .add("port", port).toString();
357 }
alshabib8ca53902014-10-07 13:11:17 -0700358
359 @Override
360 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800361 return Objects.hash(type(), port);
alshabib8ca53902014-10-07 13:11:17 -0700362 }
363
364 @Override
365 public boolean equals(Object obj) {
366 if (this == obj) {
367 return true;
368 }
369 if (obj instanceof OutputInstruction) {
370 OutputInstruction that = (OutputInstruction) obj;
Yuta HIGUCHI4ce65292014-11-01 12:09:55 -0700371 return Objects.equals(port, that.port);
alshabib8ca53902014-10-07 13:11:17 -0700372
373 }
374 return false;
375 }
alshabib55a55d92014-09-16 11:59:31 -0700376 }
377
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800378 /**
379 * Group Instruction.
sangho8995ac52015-02-04 11:29:03 -0800380 */
sangho8995ac52015-02-04 11:29:03 -0800381 public static final class GroupInstruction implements Instruction {
382 private final GroupId groupId;
383
384 private GroupInstruction(GroupId groupId) {
385 this.groupId = groupId;
386 }
387
388 public GroupId groupId() {
389 return groupId;
390 }
391
392 @Override
393 public Type type() {
394 return Type.GROUP;
395 }
alshabib9af70072015-02-09 14:34:16 -0800396
sangho8995ac52015-02-04 11:29:03 -0800397 @Override
398 public String toString() {
399 return toStringHelper(type().toString())
400 .add("group ID", groupId.id()).toString();
401 }
402
403 @Override
404 public int hashCode() {
405 return Objects.hash(type(), groupId);
406 }
407
408 @Override
409 public boolean equals(Object obj) {
410 if (this == obj) {
411 return true;
412 }
413 if (obj instanceof GroupInstruction) {
414 GroupInstruction that = (GroupInstruction) obj;
415 return Objects.equals(groupId, that.groupId);
416
417 }
418 return false;
419 }
420 }
421
alshabib9af70072015-02-09 14:34:16 -0800422
alshabibd17abc22015-04-21 18:26:35 -0700423 public static class TableTypeTransition implements Instruction {
424 private final Integer tableId;
425
426 TableTypeTransition(Integer tableId) {
427 this.tableId = tableId;
alshabib9af70072015-02-09 14:34:16 -0800428 }
429
430 @Override
431 public Type type() {
432 return Type.TABLE;
433 }
434
alshabibd17abc22015-04-21 18:26:35 -0700435 public Integer tableId() {
436 return this.tableId;
alshabib9af70072015-02-09 14:34:16 -0800437 }
438
439 @Override
440 public String toString() {
441 return toStringHelper(type().toString())
alshabibd17abc22015-04-21 18:26:35 -0700442 .add("tableId", this.tableId).toString();
alshabib9af70072015-02-09 14:34:16 -0800443 }
444
445 @Override
446 public int hashCode() {
alshabibd17abc22015-04-21 18:26:35 -0700447 return Objects.hash(type(), tableId);
alshabib9af70072015-02-09 14:34:16 -0800448 }
449
450 @Override
451 public boolean equals(Object obj) {
452 if (this == obj) {
453 return true;
454 }
455 if (obj instanceof TableTypeTransition) {
456 TableTypeTransition that = (TableTypeTransition) obj;
alshabibd17abc22015-04-21 18:26:35 -0700457 return Objects.equals(tableId, that.tableId);
alshabib9af70072015-02-09 14:34:16 -0800458
459 }
460 return false;
461 }
462
463 }
alshabib55a55d92014-09-16 11:59:31 -0700464}
alshabib8ca53902014-10-07 13:11:17 -0700465
466