blob: f422e141ecaabc36c58c5783e76218da5f11ca91 [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;
alshabib9af70072015-02-09 14:34:16 -080025import org.onosproject.net.flow.FlowRule;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.net.flow.instructions.L0ModificationInstruction.L0SubType;
27import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
28import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType;
29import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
30import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType;
31import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080032import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
sangho3f97a17d2015-01-29 22:56:29 -080033import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction;
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -080034
Jonathan Hart54b406b2015-03-06 16:24:14 -080035import java.util.Objects;
36
37import static com.google.common.base.MoreObjects.toStringHelper;
38import static com.google.common.base.Preconditions.checkNotNull;
39import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
40import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsTtlInstruction;
41import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
42import static org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
43import static org.onosproject.net.flow.instructions.L2ModificationInstruction.PopVlanInstruction;
44import static org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
alshabib64231f62014-09-16 17:58:36 -070045
alshabib55a55d92014-09-16 11:59:31 -070046/**
47 * Factory class for creating various traffic treatment instructions.
48 */
49public final class Instructions {
50
51
52 // Ban construction
53 private Instructions() {}
54
55 /**
56 * Creates an output instruction using the specified port number. This can
57 * include logical ports such as CONTROLLER, FLOOD, etc.
58 *
59 * @param number port number
60 * @return output instruction
61 */
62 public static OutputInstruction createOutput(final PortNumber number) {
63 checkNotNull(number, "PortNumber cannot be null");
64 return new OutputInstruction(number);
65 }
66
67 /**
68 * Creates a drop instruction.
Jonathan Hart54b406b2015-03-06 16:24:14 -080069 *
alshabib55a55d92014-09-16 11:59:31 -070070 * @return drop instruction
71 */
72 public static DropInstruction createDrop() {
73 return new DropInstruction();
74 }
75
76 /**
sangho8995ac52015-02-04 11:29:03 -080077 * Creates a group instruction.
78 *
79 * @param groupId Group Id
80 * @return group instruction
81 */
82 public static GroupInstruction createGroup(final GroupId groupId) {
83 checkNotNull(groupId, "GroupId cannot be null");
84 return new GroupInstruction(groupId);
85 }
86
87 /**
Marc De Leenheer49087752014-10-23 13:54:09 -070088 * Creates a l0 modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -080089 *
90 * @param lambda the lambda to modify to
Marc De Leenheer49087752014-10-23 13:54:09 -070091 * @return a l0 modification
92 */
93 public static L0ModificationInstruction modL0Lambda(short lambda) {
94 checkNotNull(lambda, "L0 lambda cannot be null");
95 return new ModLambdaInstruction(L0SubType.LAMBDA, lambda);
96 }
97
98 /**
alshabib55a55d92014-09-16 11:59:31 -070099 * Creates a l2 src modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800100 *
101 * @param addr the mac address to modify to
alshabib55a55d92014-09-16 11:59:31 -0700102 * @return a l2 modification
103 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700104 public static L2ModificationInstruction modL2Src(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -0700105 checkNotNull(addr, "Src l2 address cannot be null");
alshabib99b8fdc2014-09-25 14:30:22 -0700106 return new ModEtherInstruction(L2SubType.ETH_SRC, addr);
alshabib55a55d92014-09-16 11:59:31 -0700107 }
108
109 /**
110 * Creates a L2 dst modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800111 *
112 * @param addr the mac address to modify to
alshabib55a55d92014-09-16 11:59:31 -0700113 * @return a L2 modification
114 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700115 public static L2ModificationInstruction modL2Dst(MacAddress addr) {
alshabib55a55d92014-09-16 11:59:31 -0700116 checkNotNull(addr, "Dst l2 address cannot be null");
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800117 return new ModEtherInstruction(L2SubType.ETH_DST, addr);
alshabib55a55d92014-09-16 11:59:31 -0700118 }
119
120 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800121 * Creates a VLAN ID modification.
122 *
123 * @param vlanId the VLAN ID to modify to
alshabib7410fea2014-09-16 13:48:39 -0700124 * @return a L2 modification
125 */
Ayaka Koshibea9c199f2014-09-16 16:21:40 -0700126 public static L2ModificationInstruction modVlanId(VlanId vlanId) {
alshabib55a55d92014-09-16 11:59:31 -0700127 checkNotNull(vlanId, "VLAN id cannot be null");
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800128 return new ModVlanIdInstruction(vlanId);
alshabib55a55d92014-09-16 11:59:31 -0700129 }
130
alshabib7410fea2014-09-16 13:48:39 -0700131 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800132 * Creates a VLAN PCP modification.
133 *
134 * @param vlanPcp the PCP to modify to
alshabib7410fea2014-09-16 13:48:39 -0700135 * @return a L2 modification
136 */
137 public static L2ModificationInstruction modVlanPcp(Byte vlanPcp) {
138 checkNotNull(vlanPcp, "VLAN Pcp cannot be null");
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800139 return new ModVlanPcpInstruction(vlanPcp);
alshabib7410fea2014-09-16 13:48:39 -0700140 }
141
142 /**
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800143 * Creates a MPLS label modification.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800144 *
145 * @param mplsLabel MPLS label to set
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800146 * @return a L2 Modification
147 */
Michele Santuari4b6019e2014-12-19 11:31:45 +0100148 public static L2ModificationInstruction modMplsLabel(MplsLabel mplsLabel) {
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800149 checkNotNull(mplsLabel, "MPLS label cannot be null");
150 return new ModMplsLabelInstruction(mplsLabel);
151 }
sangho3f97a17d2015-01-29 22:56:29 -0800152
153 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800154 * Creates a MPLS decrement TTL modification.
sangho3f97a17d2015-01-29 22:56:29 -0800155 *
156 * @return a L2 Modification
157 */
158 public static L2ModificationInstruction decMplsTtl() {
159 return new ModMplsTtlInstruction();
160 }
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800161
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800162 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800163 * Creates a L3 IPv4 src modification.
164 *
165 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700166 * @return a L3 modification
167 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700168 public static L3ModificationInstruction modL3Src(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800169 checkNotNull(addr, "Src l3 IPv4 address cannot be null");
170 return new ModIPInstruction(L3SubType.IPV4_SRC, addr);
alshabib7410fea2014-09-16 13:48:39 -0700171 }
172
173 /**
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800174 * Creates a L3 IPv4 dst modification.
175 *
176 * @param addr the IPv4 address to modify to
alshabib7410fea2014-09-16 13:48:39 -0700177 * @return a L3 modification
178 */
Pavlin Radoslavov855ea2d2014-10-30 15:32:39 -0700179 public static L3ModificationInstruction modL3Dst(IpAddress addr) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800180 checkNotNull(addr, "Dst l3 IPv4 address cannot be null");
181 return new ModIPInstruction(L3SubType.IPV4_DST, addr);
182 }
183
184 /**
185 * Creates a L3 IPv6 src modification.
186 *
187 * @param addr the IPv6 address to modify to
188 * @return a L3 modification
189 */
190 public static L3ModificationInstruction modL3IPv6Src(IpAddress addr) {
191 checkNotNull(addr, "Src l3 IPv6 address cannot be null");
192 return new ModIPInstruction(L3SubType.IPV6_SRC, addr);
193 }
194
195 /**
196 * Creates a L3 IPv6 dst modification.
197 *
198 * @param addr the IPv6 address to modify to
199 * @return a L3 modification
200 */
201 public static L3ModificationInstruction modL3IPv6Dst(IpAddress addr) {
202 checkNotNull(addr, "Dst l3 IPv6 address cannot be null");
203 return new ModIPInstruction(L3SubType.IPV6_DST, addr);
204 }
205
206 /**
207 * Creates a L3 IPv6 Flow Label modification.
208 *
209 * @param flowLabel the IPv6 flow label to modify to (20 bits)
210 * @return a L3 modification
211 */
212 public static L3ModificationInstruction modL3IPv6FlowLabel(int flowLabel) {
213 return new ModIPv6FlowLabelInstruction(flowLabel);
alshabib7410fea2014-09-16 13:48:39 -0700214 }
215
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800216 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800217 * Creates a L3 decrement TTL modification.
218 *
sangho3f97a17d2015-01-29 22:56:29 -0800219 * @return a L3 modification
220 */
221 public static L3ModificationInstruction decNwTtl() {
222 return new ModTtlInstruction(L3SubType.DEC_TTL);
223 }
224
225 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800226 * Creates a L3 copy TTL to outer header modification.
227 *
sangho3f97a17d2015-01-29 22:56:29 -0800228 * @return a L3 modification
229 */
230 public static L3ModificationInstruction copyTtlOut() {
231 return new ModTtlInstruction(L3SubType.TTL_OUT);
232 }
233
234 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800235 * Creates a L3 copy TTL to inner header modification.
236 *
sangho3f97a17d2015-01-29 22:56:29 -0800237 * @return a L3 modification
238 */
239 public static L3ModificationInstruction copyTtlIn() {
240 return new ModTtlInstruction(L3SubType.TTL_IN);
241 }
242
243 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800244 * Creates a push MPLS header instruction.
245 *
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800246 * @return a L2 modification.
247 */
248 public static Instruction pushMpls() {
249 return new PushHeaderInstructions(L2SubType.MPLS_PUSH,
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800250 Ethernet.MPLS_UNICAST);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800251 }
252
253 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800254 * Creates a pop MPLS header instruction.
255 *
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800256 * @return a L2 modification.
257 */
258 public static Instruction popMpls() {
259 return new PushHeaderInstructions(L2SubType.MPLS_POP,
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800260 Ethernet.MPLS_UNICAST);
Praseed Balakrishnan8c67d172014-11-10 10:15:41 -0800261 }
alshabib7410fea2014-09-16 13:48:39 -0700262
sangho3f97a17d2015-01-29 22:56:29 -0800263 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800264 * Creates a pop MPLS header instruction with a particular ethertype.
sangho3f97a17d2015-01-29 22:56:29 -0800265 *
266 * @param etherType Ethernet type to set
267 * @return a L2 modification.
268 */
269 public static Instruction popMpls(Short etherType) {
270 checkNotNull(etherType, "Ethernet type cannot be null");
Yuta HIGUCHI32a53c52015-02-08 01:25:40 -0800271 return new PushHeaderInstructions(L2SubType.MPLS_POP, etherType);
sangho3f97a17d2015-01-29 22:56:29 -0800272 }
273
Saurav Dasfbe25c52015-03-04 11:12:00 -0800274 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800275 * Creates a pop VLAN header instruction.
276 *
277 * @return a L2 modification
Saurav Dasfbe25c52015-03-04 11:12:00 -0800278 */
279 public static Instruction popVlan() {
280 return new PopVlanInstruction(L2SubType.VLAN_POP);
281 }
282
283 /**
Jonathan Hart54b406b2015-03-06 16:24:14 -0800284 * Creates a push VLAN header instruction.
285 *
286 * @return a L2 modification
287 */
288 public static Instruction pushVlan() {
289 return new PushHeaderInstructions(L2SubType.VLAN_PUSH, Ethernet.TYPE_VLAN);
290 }
291
292 /**
Saurav Dasfbe25c52015-03-04 11:12:00 -0800293 * Sends the packet to the table described in 'type'.
Jonathan Hart54b406b2015-03-06 16:24:14 -0800294 *
Thomas Vachuska3e2b6512015-03-05 09:25:03 -0800295 * @param type flow rule table type
296 * @return table type transition instruction
Saurav Dasfbe25c52015-03-04 11:12:00 -0800297 */
alshabib9af70072015-02-09 14:34:16 -0800298 public static Instruction transition(FlowRule.Type type) {
299 checkNotNull(type, "Table type cannot be null");
300 return new TableTypeTransition(type);
301 }
302
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800303 /**
304 * Drop instruction.
alshabib55a55d92014-09-16 11:59:31 -0700305 */
alshabib55a55d92014-09-16 11:59:31 -0700306 public static final class DropInstruction implements Instruction {
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800307
308 private DropInstruction() {}
309
alshabib55a55d92014-09-16 11:59:31 -0700310 @Override
311 public Type type() {
312 return Type.DROP;
313 }
alshabib99b8fdc2014-09-25 14:30:22 -0700314
315 @Override
316 public String toString() {
alshabib346b5b32015-03-06 00:42:16 -0800317 return toStringHelper(type().toString()).toString();
alshabib99b8fdc2014-09-25 14:30:22 -0700318 }
alshabib8ca53902014-10-07 13:11:17 -0700319
320 @Override
321 public int hashCode() {
322 return Objects.hash(type());
323 }
324
325 @Override
326 public boolean equals(Object obj) {
327 if (this == obj) {
328 return true;
329 }
330 if (obj instanceof DropInstruction) {
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800331 return true;
alshabib8ca53902014-10-07 13:11:17 -0700332 }
333 return false;
334 }
alshabib55a55d92014-09-16 11:59:31 -0700335 }
336
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800337 /**
338 * Output Instruction.
sangho8995ac52015-02-04 11:29:03 -0800339 */
alshabib55a55d92014-09-16 11:59:31 -0700340 public static final class OutputInstruction implements Instruction {
341 private final PortNumber port;
342
343 private OutputInstruction(PortNumber port) {
344 this.port = port;
345 }
346
347 public PortNumber port() {
348 return port;
349 }
350
351 @Override
352 public Type type() {
353 return Type.OUTPUT;
354 }
alshabib99b8fdc2014-09-25 14:30:22 -0700355 @Override
356 public String toString() {
357 return toStringHelper(type().toString())
358 .add("port", port).toString();
359 }
alshabib8ca53902014-10-07 13:11:17 -0700360
361 @Override
362 public int hashCode() {
Thomas Vachuska9b2da212014-11-10 19:30:25 -0800363 return Objects.hash(type(), port);
alshabib8ca53902014-10-07 13:11:17 -0700364 }
365
366 @Override
367 public boolean equals(Object obj) {
368 if (this == obj) {
369 return true;
370 }
371 if (obj instanceof OutputInstruction) {
372 OutputInstruction that = (OutputInstruction) obj;
Yuta HIGUCHI4ce65292014-11-01 12:09:55 -0700373 return Objects.equals(port, that.port);
alshabib8ca53902014-10-07 13:11:17 -0700374
375 }
376 return false;
377 }
alshabib55a55d92014-09-16 11:59:31 -0700378 }
379
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800380 /**
381 * Group Instruction.
sangho8995ac52015-02-04 11:29:03 -0800382 */
sangho8995ac52015-02-04 11:29:03 -0800383 public static final class GroupInstruction implements Instruction {
384 private final GroupId groupId;
385
386 private GroupInstruction(GroupId groupId) {
387 this.groupId = groupId;
388 }
389
390 public GroupId groupId() {
391 return groupId;
392 }
393
394 @Override
395 public Type type() {
396 return Type.GROUP;
397 }
alshabib9af70072015-02-09 14:34:16 -0800398
sangho8995ac52015-02-04 11:29:03 -0800399 @Override
400 public String toString() {
401 return toStringHelper(type().toString())
402 .add("group ID", groupId.id()).toString();
403 }
404
405 @Override
406 public int hashCode() {
407 return Objects.hash(type(), groupId);
408 }
409
410 @Override
411 public boolean equals(Object obj) {
412 if (this == obj) {
413 return true;
414 }
415 if (obj instanceof GroupInstruction) {
416 GroupInstruction that = (GroupInstruction) obj;
417 return Objects.equals(groupId, that.groupId);
418
419 }
420 return false;
421 }
422 }
423
alshabib9af70072015-02-09 14:34:16 -0800424 // FIXME: Temporary support for this. This should probably become it's own
425 // type like other instructions.
426 public static class TableTypeTransition implements Instruction {
427 private final FlowRule.Type tableType;
428
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800429 TableTypeTransition(FlowRule.Type type) {
alshabib9af70072015-02-09 14:34:16 -0800430 this.tableType = type;
431 }
432
433 @Override
434 public Type type() {
435 return Type.TABLE;
436 }
437
438 public FlowRule.Type tableType() {
439 return this.tableType;
440 }
441
442 @Override
443 public String toString() {
444 return toStringHelper(type().toString())
Yuta HIGUCHI6a479642015-02-08 01:28:50 -0800445 .add("tableType", this.tableType).toString();
alshabib9af70072015-02-09 14:34:16 -0800446 }
447
448 @Override
449 public int hashCode() {
450 return Objects.hash(type(), tableType);
451 }
452
453 @Override
454 public boolean equals(Object obj) {
455 if (this == obj) {
456 return true;
457 }
458 if (obj instanceof TableTypeTransition) {
459 TableTypeTransition that = (TableTypeTransition) obj;
460 return Objects.equals(tableType, that.tableType);
461
462 }
463 return false;
464 }
465
466 }
alshabib55a55d92014-09-16 11:59:31 -0700467}
alshabib8ca53902014-10-07 13:11:17 -0700468
469