blob: 37820fb4678609f10106fdd7b00119a4e8b87e5b [file] [log] [blame]
Toshio Koidea03915e2014-07-01 18:39:52 -07001package net.onrc.onos.api.flowmanager;
2
Toshio Koide9aa4c0f2014-08-11 16:06:44 -07003import static com.google.common.base.Preconditions.checkNotNull;
Toshio Koidec79d2642014-08-19 01:09:08 -07004import static com.google.common.base.Preconditions.checkState;
Toshio Koide9aa4c0f2014-08-11 16:06:44 -07005
Toshio Koidec79d2642014-08-19 01:09:08 -07006import java.util.Arrays;
7import java.util.Iterator;
8import java.util.LinkedList;
Toshio Koidea03915e2014-07-01 18:39:52 -07009import java.util.List;
10
Toshio Koided7d550c2014-08-21 16:08:55 -070011import net.onrc.onos.api.flowmanager.FlowBatchOperation.Operator;
Toshio Koidec79d2642014-08-19 01:09:08 -070012import net.onrc.onos.core.matchaction.MatchAction;
Toshio Koided7d550c2014-08-21 16:08:55 -070013import net.onrc.onos.core.matchaction.MatchActionIdGenerator;
Toshio Koidec79d2642014-08-19 01:09:08 -070014import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
Ray Milkey42ae1b52014-08-15 16:37:06 -070015import net.onrc.onos.core.matchaction.MatchActionOperations;
Toshio Koided7d550c2014-08-21 16:08:55 -070016import net.onrc.onos.core.matchaction.MatchActionOperationsIdGenerator;
Toshio Koided8b077a2014-08-13 10:47:21 -070017import net.onrc.onos.core.matchaction.action.Action;
Toshio Koidec79d2642014-08-19 01:09:08 -070018import net.onrc.onos.core.matchaction.action.OutputAction;
Toshio Koidea03915e2014-07-01 18:39:52 -070019import net.onrc.onos.core.matchaction.match.PacketMatch;
20import net.onrc.onos.core.util.PortNumber;
Toshio Koidec79d2642014-08-19 01:09:08 -070021import net.onrc.onos.core.util.SwitchPort;
Toshio Koidea03915e2014-07-01 18:39:52 -070022
23/**
Toshio Koide7894ca02014-08-15 14:30:13 -070024 * Flow object representing a packet path.
Toshio Koidea03915e2014-07-01 18:39:52 -070025 * <p>
26 * TODO: Think this: Do we need a bandwidth constraint?
27 */
28public class PacketPathFlow extends PathFlow {
Toshio Koide9aa4c0f2014-08-11 16:06:44 -070029 private final PacketMatch match;
30 private final int hardTimeout;
31 private final int idleTimeout;
Toshio Koidea03915e2014-07-01 18:39:52 -070032
33 /**
Toshio Koide2c67a2d2014-08-27 11:30:56 -070034 * Default constructor for Kryo deserialization.
35 */
36 @Deprecated
37 protected PacketPathFlow() {
38 match = null;
39 hardTimeout = 0;
40 idleTimeout = 0;
41 }
42
43 /**
Toshio Koidea03915e2014-07-01 18:39:52 -070044 * Constructor.
45 *
Toshio Koide9aa4c0f2014-08-11 16:06:44 -070046 * @param id ID for this new Flow object
47 * @param match the Match object at the source node of the path
48 * @param ingressPort the Ingress port number at the ingress edge node
49 * @param path the Path between ingress and egress edge node
50 * @param egressActions the list of Action objects at the egress edge node
51 * @param hardTimeout the hard-timeout value in seconds, or 0 for no timeout
52 * @param idleTimeout the idle-timeout value in seconds, or 0 for no timeout
Toshio Koidea03915e2014-07-01 18:39:52 -070053 */
Toshio Koide9aa4c0f2014-08-11 16:06:44 -070054 public PacketPathFlow(FlowId id,
55 PacketMatch match, PortNumber ingressPort, Path path,
56 List<Action> egressActions,
Toshio Koidea03915e2014-07-01 18:39:52 -070057 int hardTimeout, int idleTimeout) {
Toshio Koide9aa4c0f2014-08-11 16:06:44 -070058 super(id, ingressPort, path, egressActions);
59 this.match = checkNotNull(match);
Toshio Koidea03915e2014-07-01 18:39:52 -070060 this.hardTimeout = hardTimeout;
61 this.idleTimeout = idleTimeout;
62 }
63
64 /**
65 * Gets idle-timeout value.
66 *
67 * @return Idle-timeout value (seconds)
68 */
69 public int getIdleTimeout() {
70 return idleTimeout;
71 }
72
73 /**
74 * Gets hard-timeout value.
75 *
76 * @return Hard-timeout value (seconds)
77 */
78 public int getHardTimeout() {
79 return hardTimeout;
80 }
81
82 @Override
Toshio Koide5c5ca102014-08-19 00:49:52 -070083 public PacketMatch getMatch() {
84 return match;
85 }
86
87 @Override
Toshio Koided7d550c2014-08-21 16:08:55 -070088 public List<MatchActionOperations> compile(Operator op,
89 MatchActionIdGenerator maIdGenerator,
90 MatchActionOperationsIdGenerator maoIdGenerator) {
Toshio Koidec79d2642014-08-19 01:09:08 -070091 switch (op) {
92 case ADD:
93 return compileAddOperation(maIdGenerator, maoIdGenerator);
94 case REMOVE:
95 return compileRemoveOperation(maIdGenerator, maoIdGenerator);
96 default:
97 throw new UnsupportedOperationException("Unknown operation.");
98 }
99 }
100
101 /**
102 * Creates the next {@link MatchAction} object using iterators.
103 *
104 * @param portIterator the iterator for {@link SwitchPort} objects
105 * @param actionsIterator the iterator for the lists of {@link Action}
106 * @param maIdGenerator the ID generator of {@link MatchAction}
107 * @return {@link MatchAction} object based on the specified iterators
108 */
109 private MatchAction createNextMatchAction(Iterator<SwitchPort> portIterator,
110 Iterator<List<Action>> actionsIterator,
111 MatchActionIdGenerator maIdGenerator) {
112 if (portIterator == null || actionsIterator == null ||
113 !portIterator.hasNext() || !actionsIterator.hasNext()) {
114 return null;
115 }
116
117 // TODO: Update this after merging the new MatchAction API.
118 return new MatchAction(
119 maIdGenerator.getNewId(),
120 portIterator.next(),
121 getMatch(), actionsIterator.next());
122 }
123
124 /**
125 * Generates the list of {@link MatchActionOperations} objects with
126 * add-operation.
127 *
128 * @return the list of {@link MatchActionOperations} objects
129 */
130 private List<MatchActionOperations> compileAddOperation(
131 MatchActionIdGenerator maIdGenerator,
132 MatchActionOperationsIdGenerator maoIdGenerator) {
133 Path path = checkNotNull(getPath());
134 checkState(path.size() > 0, "Path object has no link.");
135
136 // Preparing each actions and ingress port for each switch
137 List<List<Action>> actionsList = new LinkedList<>();
138 List<SwitchPort> portList = new LinkedList<>();
139 for (FlowLink link : path) {
140 portList.add(link.getDstSwitchPort());
141 actionsList.add(Arrays.asList(
142 (Action) new OutputAction(link.getSrcPortNumber())));
143 }
144
145 // The head switch's ingress port
146 portList.add(0, new SwitchPort(path.getSrcDpid(), getIngressPortNumber()));
147
148 // The tail switch's action
149 actionsList.add(getEgressActions());
150
151 Iterator<SwitchPort> portIterator = portList.iterator();
152 Iterator<List<Action>> actionsIterator = actionsList.iterator();
153
154 // Creates the second phase operation
155 // using the head switch's match action
156 MatchAction headMatchAction = createNextMatchAction(portIterator,
157 actionsIterator, maIdGenerator);
158 if (headMatchAction == null) {
159 return null;
160 }
161 MatchActionOperations secondOp = new MatchActionOperations(
162 maoIdGenerator.getNewId());
163 secondOp.addOperation(new MatchActionOperationEntry(
164 MatchActionOperations.Operator.ADD, headMatchAction));
165
166 // Creates the first phase operation
167 // using the remaining switches' match actions
168 MatchActionOperations firstOp = new MatchActionOperations(
169 maoIdGenerator.getNewId());
170 MatchAction ma;
171 while ((ma = createNextMatchAction(portIterator, actionsIterator, maIdGenerator)) != null) {
172 firstOp.addOperation(new MatchActionOperationEntry(
173 MatchActionOperations.Operator.ADD, ma));
174 }
175
176 return Arrays.asList(firstOp, secondOp);
177 }
178
179 /**
180 * Generates the list of {@link MatchActionOperations} objects with
181 * remote-operation.
182 *
183 * @return the list of {@link MatchActionOperations} objects
184 */
185 private List<MatchActionOperations> compileRemoveOperation(
186 MatchActionIdGenerator maIdGenerator,
187 MatchActionOperationsIdGenerator maoIdGenerator) {
188 // TODO implement it
189 throw new UnsupportedOperationException(
190 "REMOVE operation is not implemented yet.");
Toshio Koidea03915e2014-07-01 18:39:52 -0700191 }
192}