blob: 2ce233f860daf47c6485cf58a2b454e737783c6c [file] [log] [blame]
alshabib1d4cace2014-09-13 19:16:26 -07001package org.onlab.onos.net.flow;
2
3import static org.slf4j.LoggerFactory.getLogger;
4
5import java.util.Collections;
6import java.util.LinkedList;
7import java.util.List;
8
alshabib010c31d2014-09-26 10:01:12 -07009import org.onlab.onos.net.PortNumber;
alshabib55a55d92014-09-16 11:59:31 -070010import org.onlab.onos.net.flow.instructions.Instruction;
alshabib010c31d2014-09-26 10:01:12 -070011import org.onlab.onos.net.flow.instructions.Instructions;
12import org.onlab.packet.IpPrefix;
13import org.onlab.packet.MacAddress;
14import org.onlab.packet.VlanId;
alshabib1d4cace2014-09-13 19:16:26 -070015import org.slf4j.Logger;
16
alshabib7b2748f2014-09-16 20:21:11 -070017public final class DefaultTrafficTreatment implements TrafficTreatment {
alshabib1d4cace2014-09-13 19:16:26 -070018
19 private final List<Instruction> instructions;
20
alshabib7b2748f2014-09-16 20:21:11 -070021 private DefaultTrafficTreatment(List<Instruction> instructions) {
alshabib1d4cace2014-09-13 19:16:26 -070022 this.instructions = Collections.unmodifiableList(instructions);
23 }
24
25 @Override
26 public List<Instruction> instructions() {
27 return instructions;
28 }
29
30 /**
31 * Builds a list of treatments following the following order.
32 * Modifications -> Group -> Output (including drop)
33 *
34 */
35
36 public static class Builder implements TrafficTreatment.Builder {
37
38 private final Logger log = getLogger(getClass());
39
alshabib030111e2014-09-15 15:56:42 -070040 boolean drop = false;
41
42 List<Instruction> outputs = new LinkedList<>();
alshabib1d4cace2014-09-13 19:16:26 -070043
44 // TODO: should be a list of instructions based on group objects
alshabib030111e2014-09-15 15:56:42 -070045 List<Instruction> groups = new LinkedList<>();
alshabib1d4cace2014-09-13 19:16:26 -070046
47 // TODO: should be a list of instructions based on modification objects
alshabib030111e2014-09-15 15:56:42 -070048 List<Instruction> modifications = new LinkedList<>();
alshabib1d4cace2014-09-13 19:16:26 -070049
alshabib1d4cace2014-09-13 19:16:26 -070050 public Builder add(Instruction instruction) {
alshabib010c31d2014-09-26 10:01:12 -070051 if (drop) {
52 return this;
53 }
alshabib1d4cace2014-09-13 19:16:26 -070054 switch (instruction.type()) {
alshabib1d4cace2014-09-13 19:16:26 -070055 case DROP:
alshabib030111e2014-09-15 15:56:42 -070056 drop = true;
57 break;
58 case OUTPUT:
alshabib1d4cace2014-09-13 19:16:26 -070059 outputs.add(instruction);
60 break;
alshabib35edb1a2014-09-16 17:44:44 -070061 case L2MODIFICATION:
62 case L3MODIFICATION:
alshabib1d4cace2014-09-13 19:16:26 -070063 // TODO: enforce modification order if any
64 modifications.add(instruction);
alshabib030111e2014-09-15 15:56:42 -070065 break;
alshabib1d4cace2014-09-13 19:16:26 -070066 case GROUP:
67 groups.add(instruction);
alshabib030111e2014-09-15 15:56:42 -070068 break;
alshabib1d4cace2014-09-13 19:16:26 -070069 default:
70 log.warn("Unknown instruction type {}", instruction.type());
71 }
72 return this;
73 }
74
75 @Override
alshabib010c31d2014-09-26 10:01:12 -070076 public void drop() {
77 add(Instructions.createDrop());
78 }
79
80 @Override
81 public Builder setOutput(PortNumber number) {
82 return add(Instructions.createOutput(number));
83 }
84
85 @Override
86 public Builder setEthSrc(MacAddress addr) {
87 return add(Instructions.modL2Src(addr));
88 }
89
90 @Override
91 public Builder setEthDst(MacAddress addr) {
92 return add(Instructions.modL2Dst(addr));
93 }
94
95 @Override
96 public Builder setVlanId(VlanId id) {
97 return add(Instructions.modVlanId(id));
98 }
99
100 @Override
101 public Builder setVlanPcp(Byte pcp) {
102 return add(Instructions.modVlanPcp(pcp));
103 }
104
105 @Override
106 public Builder setIpSrc(IpPrefix addr) {
107 return add(Instructions.modL3Src(addr));
108 }
109
110 @Override
111 public Builder setIpDst(IpPrefix addr) {
112 return add(Instructions.modL3Dst(addr));
113 }
114
115 @Override
alshabib1d4cace2014-09-13 19:16:26 -0700116 public TrafficTreatment build() {
alshabib030111e2014-09-15 15:56:42 -0700117
118 //If we are dropping should we just return an emptry list?
alshabib1d4cace2014-09-13 19:16:26 -0700119 List<Instruction> instructions = new LinkedList<Instruction>();
120 instructions.addAll(modifications);
121 instructions.addAll(groups);
alshabib030111e2014-09-15 15:56:42 -0700122 if (!drop) {
123 instructions.addAll(outputs);
124 }
alshabib1d4cace2014-09-13 19:16:26 -0700125
126 return new DefaultTrafficTreatment(instructions);
127 }
128
129 }
130
131}