blob: e68d04bc577361892d648ace5a3624f32c2de0bc [file] [log] [blame]
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001package net.onrc.onos.ofcontroller.flowmanager;
2
3import java.io.PrintWriter;
4import java.io.StringWriter;
5import java.util.ArrayList;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07006import java.util.LinkedList;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08007import java.util.Map;
8
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07009import net.floodlightcontroller.util.MACAddress;
yoshitomob292c622013-11-23 14:35:58 -080010import net.onrc.onos.graph.DBOperation;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -080011import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070012import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
13import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
14import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
15import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
16import net.onrc.onos.ofcontroller.util.*;
17
18import org.slf4j.Logger;
19import org.slf4j.LoggerFactory;
20
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080021import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -080022import com.tinkerpop.blueprints.impls.ramcloud.RamCloudVertex;
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080023
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070024/**
25 * Class for performing Flow-related operations on the Database.
26 */
Pavlin Radoslavov6bfaea62013-12-03 14:55:57 -080027public class FlowDatabaseOperation {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070028 private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080029 private static final boolean measureONOSFlowTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlow", "0")) != 0;
30 private static final boolean measureONOSFlowEntryTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlowEntry", "0")) != 0;
Toshio Koidec71b7122014-01-13 15:16:53 -080031 private static final boolean useFastAddFlow = true;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070032
33 /**
34 * Add a flow.
35 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070036 * @param dbHandler the Graph Database handler to use.
37 * @param flowPath the Flow Path to install.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070038 * @return true on success, otherwise false.
39 */
Toshio Koidec71b7122014-01-13 15:16:53 -080040 static boolean addFlowFast(DBOperation dbHandler, FlowPath flowPath) {
41 IFlowPath flowPathObj = null;
42 FlowPathProperty flowProp = new FlowPathProperty();
43
44 flowPathObj = dbHandler.searchFlowPath(flowPath.flowId()); // toshi memo: getVertices("flow_id")
45 if (flowPathObj == null) {
46 try {
47 flowPathObj = dbHandler.newFlowPath(); // toshi memo: addVertex(), setType("flow")
48 } catch (Exception e) {
49 flowPathObj = null;
50 StringWriter sw = new StringWriter();
51 e.printStackTrace(new PrintWriter(sw));
52 log.error(":addFlow FlowId:{} failed: {}", flowPath.flowId(), sw.toString());
53 }
54 flowProp.setFlowPathUserState("FP_USER_ADD");
55 } else {
56 // Remove the old Flow Entries (this is special for RAMCloud)
57 for (IFlowEntry flowEntryObj : flowPathObj.getFlowEntries()) { // toshi memo: get.@Adjacency("flow", IN)
58 //flowObj.removeFlowEntry(flowEntryObj); // toshi memo: remove.@Adjacency("flow", IN)
59 dbHandler.removeFlowEntry(flowEntryObj); // toshi memo: removeVertex()
60 }
61 flowProp.setFlowPathUserState("FP_USER_MODIFY");
62 }
63 if (flowPathObj == null) {
64 log.error(":addFlow FlowId:{} failed: Flow object not created", flowPath.flowId());
65 dbHandler.rollback();
66
67 return false;
68 }
69
70 // Set the Flow key
71 flowProp.setFlowId(flowPath.flowId().toString());
72
73 // Set the Flow attributes
74 flowProp.setInstallerId(flowPath.installerId().toString());
75 flowProp.setFlowPathType(flowPath.flowPathType().toString());
76 flowProp.setFlowPathUserState(flowPath.flowPathUserState().toString());
77 flowProp.setFlowPathFlags(flowPath.flowPathFlags().flags());
78 flowProp.setIdleTimeout(flowPath.idleTimeout());
79 flowProp.setHardTimeout(flowPath.hardTimeout());
80 flowProp.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
81 flowProp.setSrcPort(flowPath.dataPath().srcPort().port().value());
82 flowProp.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
83 flowProp.setDstPort(flowPath.dataPath().dstPort().port().value());
84
85 if (flowPath.flowEntryMatch().matchSrcMac()) {
86 flowProp.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
87 }
88 if (flowPath.flowEntryMatch().matchDstMac()) {
89 flowProp.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
90 }
91 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
92 flowProp.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
93 }
94 if (flowPath.flowEntryMatch().matchVlanId()) {
95 flowProp.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
96 }
97 if (flowPath.flowEntryMatch().matchVlanPriority()) {
98 flowProp.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
99 }
100 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
101 flowProp.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
102 }
103 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
104 flowProp.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
105 }
106 if (flowPath.flowEntryMatch().matchIpProto()) {
107 flowProp.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
108 }
109 if (flowPath.flowEntryMatch().matchIpToS()) {
110 flowProp.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
111 }
112 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
113 flowProp.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
114 }
115 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
116 flowProp.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
117 }
118 if (! flowPath.flowEntryActions().actions().isEmpty()) {
119 flowProp.setActions(flowPath.flowEntryActions().toString());
120 }
121 flowProp.setDataPathSummary(flowPath.dataPath().dataPathSummary());
122
123 flowProp.commitProperties(dbHandler, flowPathObj); // toshi memo: flowObj.setProperties()
124
125 //
126 // Flow Entries:
127 // flowPath.dataPath().flowEntries()
128 //
129 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
130 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
131 continue; // Skip: all Flow Entries were deleted earlier
132
133 IFlowEntry iFlowEntry = null;
134 FlowEntryProperty flowEntryProp = new FlowEntryProperty();
135
136 try {
137 iFlowEntry = dbHandler.searchFlowEntry(flowEntry.flowEntryId()); // toshi memo: getVertices()
138 if (iFlowEntry != null) {
139 flowEntryProp.setUserState("FE_USER_MODIFY");
140 } else {
141 flowEntryProp.setUserState("FE_USER_ADD");
142 iFlowEntry = dbHandler.newFlowEntry(); // toshi memo: addVertex(). setType("flow_entry")
143 //flowObj.addFlowEntry(iFlowEntry); // toshi memo: add.@Adjacency("flow", IN)
144 iFlowEntry.setFlow(flowPathObj); // toshi memo: set.@Adjacency("flow")
145 }
146 } catch (Exception e) {
147 iFlowEntry = null;
148 }
149 if (iFlowEntry == null) {
150 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created", flowEntry.flowEntryId());
151 dbHandler.rollback();
152 return false;
153 }
154
155 // Set the Flow Entry key
156 flowEntryProp.setFlowEntryId(flowEntry.flowEntryId().toString());
157 flowEntryProp.setType("flow_entry");
158
159 // Set the Flow Entry Edges
160 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString()); // toshi memo: getVertices()
161
162 flowEntryProp.setIdleTimeout(flowEntry.idleTimeout());
163 flowEntryProp.setHardTimeout(flowEntry.hardTimeout());
164 flowEntryProp.setSwitchDpid(flowEntry.dpid().toString());
165
166 iFlowEntry.setSwitch(sw); // toshi memo: set.@Adjacency("switch")
167 if (flowEntry.flowEntryMatch().matchInPort()) {
168 IPortObject inport = dbHandler.searchPort(flowEntry.dpid().toString(), flowEntry.flowEntryMatch().inPort().value()); // toshi memo: getVertices()
169 flowEntryProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
170 iFlowEntry.setInPort(inport); // toshi memo: set.@Adjacency("inport")
171 }
172
173 // Set the Flow Entry attributes
174 if (flowEntry.flowEntryMatch().matchSrcMac()) {
175 flowEntryProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
176 }
177 if (flowEntry.flowEntryMatch().matchDstMac()) {
178 flowEntryProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
179 }
180 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
181 flowEntryProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
182 }
183 if (flowEntry.flowEntryMatch().matchVlanId()) {
184 flowEntryProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
185 }
186 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
187 flowEntryProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
188 }
189 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
190 flowEntryProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
191 }
192 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
193 flowEntryProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
194 }
195 if (flowEntry.flowEntryMatch().matchIpProto()) {
196 flowEntryProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
197 }
198 if (flowEntry.flowEntryMatch().matchIpToS()) {
199 flowEntryProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
200 }
201 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
202 flowEntryProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
203 }
204 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
205 flowEntryProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
206 }
207
208 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
209 if (fa.actionOutput() != null) {
210 IPortObject outport = dbHandler.searchPort(flowEntry.dpid().toString(), fa.actionOutput().port().value()); // toshi memo: getVertices()
211 flowEntryProp.setActionOutputPort(fa.actionOutput().port().value());
212 iFlowEntry.setOutPort(outport); // set.@Adjacency("outport")
213 }
214 }
215 if (! flowEntry.flowEntryActions().isEmpty()) {
216 flowEntryProp.setActions(flowEntry.flowEntryActions().toString());
217 }
218
219 flowEntryProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
220 flowEntryProp.commitProperties(dbHandler, iFlowEntry); // toshi memo: setProperties()
221 }
222
223 dbHandler.commit();
224 return true;
225 }
226
227 /**
228 * Add a flow.
229 *
230 * @param dbHandler the Graph Database handler to use.
231 * @param flowPath the Flow Path to install.
232 * @return true on success, otherwise false.
233 */
onlab-qa38805cd2013-12-06 20:08:54 -0800234 static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
Toshio Koidec71b7122014-01-13 15:16:53 -0800235 if (useFastAddFlow)
236 return addFlowFast(dbHandler, flowPath);
237
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700238 IFlowPath flowObj = null;
239 boolean found = false;
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800240 long startAddFlow = 0;
241 long endAddFlow = 0;
242 long endSearchExistingFlowPathTime = 0;
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800243 long startCreateNewFlowPathTime = 0;
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800244 long endCreateNewFlowPathTime = 0;
245 long startFollowExistingFlowEntries = 0;
246 long endFollowExistingFlowEntries = 0;
247 long accTimeRemovingFlowEntriesFromFlowPath = 0;
248 long accTimeRemovingFlowEntriesFromDB = 0;
249 long startSettingFlowPathProps = 0;
250 long endSettingFlowPathProps = 0;
251 int numPropsSet = 0;
252 long accTimeAddFlowEntries = 0;
253 int numNewFlowEntries = 0;
254 LinkedList<long[]> flowEntryTimes = new LinkedList<>();
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800255 PerfMon pm = PerfMon.getInstance();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800256
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800257 pm.addflowpath_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700258 try {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800259 if ( measureONOSFlowTimeProp ) {
260 startAddFlow = System.nanoTime();
261 }
yoshi40210942013-12-03 08:21:02 -0800262 flowObj = dbHandler.searchFlowPath(flowPath.flowId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800263 if ( measureONOSFlowTimeProp ) {
264 endSearchExistingFlowPathTime = System.nanoTime();
265 }
yoshi40210942013-12-03 08:21:02 -0800266 if (flowObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700267 found = true;
268 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800269 if ( measureONOSFlowTimeProp ) {
270 startCreateNewFlowPathTime = System.nanoTime();
271 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700272 flowObj = dbHandler.newFlowPath();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800273 if ( measureONOSFlowTimeProp ) {
274 endCreateNewFlowPathTime = System.nanoTime();
275 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700276 }
277 } catch (Exception e) {
278 dbHandler.rollback();
279
280 StringWriter sw = new StringWriter();
281 e.printStackTrace(new PrintWriter(sw));
282 String stacktrace = sw.toString();
283
284 log.error(":addFlow FlowId:{} failed: {}",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800285 flowPath.flowId(),
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700286 stacktrace);
287 return false;
288 }
289 if (flowObj == null) {
290 log.error(":addFlow FlowId:{} failed: Flow object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800291 flowPath.flowId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700292 dbHandler.rollback();
293 return false;
294 }
295
296 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800297 // Remove the old Flow Entries
298 //
299 if (found) {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800300 if ( measureONOSFlowTimeProp ) {
301 startFollowExistingFlowEntries = System.nanoTime();
302 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800303 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800304 if ( measureONOSFlowTimeProp ) {
305 endFollowExistingFlowEntries = System.nanoTime();
306 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800307 LinkedList<IFlowEntry> deleteFlowEntries =
308 new LinkedList<IFlowEntry>();
309 for (IFlowEntry flowEntryObj : flowEntries)
310 deleteFlowEntries.add(flowEntryObj);
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800311 if( measureONOSFlowTimeProp ) {
312 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
313 long start = System.nanoTime();
314 flowObj.removeFlowEntry(flowEntryObj);
315 accTimeRemovingFlowEntriesFromFlowPath += System.nanoTime() - start;
316 start = System.nanoTime();
317 dbHandler.removeFlowEntry(flowEntryObj);
318 accTimeRemovingFlowEntriesFromDB += System.nanoTime() - start;
319 }
320 } else {
321 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
322 flowObj.removeFlowEntry(flowEntryObj);
323 dbHandler.removeFlowEntry(flowEntryObj);
324 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800325 }
326 }
327
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800328 if ( measureONOSFlowTimeProp ) {
329 startSettingFlowPathProps = System.nanoTime();
330 }
Toshio Koidea9b25142014-01-10 01:15:57 -0800331
Toshio Koidec71b7122014-01-13 15:16:53 -0800332 FlowPathProperty flowProp = new FlowPathProperty();
Toshio Koidea9b25142014-01-10 01:15:57 -0800333
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800334 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700335 // Set the Flow key:
336 // - flowId
337 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800338 flowProp.setFlowId(flowPath.flowId().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800339 if ( measureONOSFlowTimeProp ) {
340 numPropsSet += 2;
341 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700342
343 //
344 // Set the Flow attributes:
345 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700346 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700347 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700348 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800349 // - flowPath.idleTimeout()
350 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700351 // - flowPath.dataPath().srcPort()
352 // - flowPath.dataPath().dstPort()
353 // - flowPath.matchSrcMac()
354 // - flowPath.matchDstMac()
355 // - flowPath.matchEthernetFrameType()
356 // - flowPath.matchVlanId()
357 // - flowPath.matchVlanPriority()
358 // - flowPath.matchSrcIPv4Net()
359 // - flowPath.matchDstIPv4Net()
360 // - flowPath.matchIpProto()
361 // - flowPath.matchIpToS()
362 // - flowPath.matchSrcTcpUdpPort()
363 // - flowPath.matchDstTcpUdpPort()
364 // - flowPath.flowEntryActions()
365 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800366 flowProp.setInstallerId(flowPath.installerId().toString());
367 flowProp.setFlowPathType(flowPath.flowPathType().toString());
368 flowProp.setFlowPathUserState(flowPath.flowPathUserState().toString());
369 flowProp.setFlowPathFlags(flowPath.flowPathFlags().flags());
370 flowProp.setIdleTimeout(flowPath.idleTimeout());
371 flowProp.setHardTimeout(flowPath.hardTimeout());
372 flowProp.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
373 flowProp.setSrcPort(flowPath.dataPath().srcPort().port().value());
374 flowProp.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
375 flowProp.setDstPort(flowPath.dataPath().dstPort().port().value());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800376 if ( measureONOSFlowTimeProp ) {
377 numPropsSet += 10;
378 }
379
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700380 if (flowPath.flowEntryMatch().matchSrcMac()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800381 flowProp.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800382 if ( measureONOSFlowTimeProp ) {
383 ++numPropsSet;
384 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700385 }
386 if (flowPath.flowEntryMatch().matchDstMac()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800387 flowProp.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800388 if ( measureONOSFlowTimeProp ) {
389 ++numPropsSet;
390 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700391 }
392 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800393 flowProp.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800394 if ( measureONOSFlowTimeProp ) {
395 ++numPropsSet;
396 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700397 }
398 if (flowPath.flowEntryMatch().matchVlanId()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800399 flowProp.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800400 if ( measureONOSFlowTimeProp ) {
401 ++numPropsSet;
402 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700403 }
404 if (flowPath.flowEntryMatch().matchVlanPriority()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800405 flowProp.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800406 if ( measureONOSFlowTimeProp ) {
407 ++numPropsSet;
408 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700409 }
410 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800411 flowProp.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800412 if ( measureONOSFlowTimeProp ) {
413 ++numPropsSet;
414 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700415 }
416 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800417 flowProp.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800418 if ( measureONOSFlowTimeProp ) {
419 ++numPropsSet;
420 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700421 }
422 if (flowPath.flowEntryMatch().matchIpProto()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800423 flowProp.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800424 if ( measureONOSFlowTimeProp ) {
425 ++numPropsSet;
426 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700427 }
428 if (flowPath.flowEntryMatch().matchIpToS()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800429 flowProp.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800430 if ( measureONOSFlowTimeProp ) {
431 ++numPropsSet;
432 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700433 }
434 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800435 flowProp.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800436 if ( measureONOSFlowTimeProp ) {
437 ++numPropsSet;
438 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700439 }
440 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800441 flowProp.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800442 if ( measureONOSFlowTimeProp ) {
443 ++numPropsSet;
444 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700445 }
446 if (! flowPath.flowEntryActions().actions().isEmpty()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800447 flowProp.setActions(flowPath.flowEntryActions().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800448 if ( measureONOSFlowTimeProp ) {
449 ++numPropsSet;
450 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700451 }
Toshio Koidea9b25142014-01-10 01:15:57 -0800452 flowProp.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800453 if ( measureONOSFlowTimeProp ) {
454 ++numPropsSet;
455 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700456
457 if (found)
Toshio Koidea9b25142014-01-10 01:15:57 -0800458 flowProp.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700459 else
Toshio Koidea9b25142014-01-10 01:15:57 -0800460 flowProp.setFlowPathUserState("FP_USER_ADD");
461
Toshio Koidec71b7122014-01-13 15:16:53 -0800462 flowProp.commitProperties(dbHandler, flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700463
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800464 if ( measureONOSFlowTimeProp ) {
465 ++numPropsSet;
466 }
467
468 if ( measureONOSFlowTimeProp ) {
469 endSettingFlowPathProps = System.nanoTime();
470 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800471 pm.addflowpath_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700472 // Flow edges:
473 // HeadFE
474
475
476 //
477 // Flow Entries:
478 // flowPath.dataPath().flowEntries()
479 //
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800480 pm.addflowentry_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700481 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800482 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
483 continue; // Skip: all Flow Entries were deleted earlier
484
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800485 pm.addflowentry_incr();
486
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800487 long startAddFlowEntry = 0, endAddFlowEntry;
488 if( measureONOSFlowTimeProp ) {
489 startAddFlowEntry = System.nanoTime();
490 }
491 IFlowEntry iFlowEntry = addFlowEntry(dbHandler, flowObj, flowEntry);
492 if( measureONOSFlowTimeProp ) {
493 endAddFlowEntry = System.nanoTime();
494 accTimeAddFlowEntries += endAddFlowEntry - startAddFlowEntry;
495
496 flowEntryTimes.addLast( new long[]{flowEntry.flowId().value(), endAddFlowEntry - startAddFlowEntry} );
497 }
498 if ( iFlowEntry == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700499 dbHandler.rollback();
500 return false;
501 }
502 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800503 pm.addflowentry_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700504 dbHandler.commit();
505
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800506
507 if ( measureONOSFlowTimeProp ) {
508 endAddFlow = System.nanoTime();
509
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800510 log.error("Performance addFlow(_,{}) -- "
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800511 + "GrandTotal: {} "
512 + "only FlowPathTotal: {} "
513 + "searchExistingFlowPath: {} "
514 + "createNewFlowPathTime: {}"
515 + "followExistingFlowEntries: {} "
516 + "accTimeRemovingFlowEntriesFromFlowPath: {} "
517 + "accTimeRemovingFlowEntriesFromDB: {} "
518 + "settingFlowPathProps: {} #Props: {} "
519 + "accFlowEntries: {} #FEs: {}",
520 flowPath.flowId(),
521 (endAddFlow - startAddFlow),
522 (endSettingFlowPathProps - startAddFlow),
523 (endSearchExistingFlowPathTime - startAddFlow),
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800524 (endCreateNewFlowPathTime - startCreateNewFlowPathTime),
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800525 (endFollowExistingFlowEntries - startFollowExistingFlowEntries),
526 (accTimeRemovingFlowEntriesFromFlowPath),
527 (accTimeRemovingFlowEntriesFromDB),
528 (endSettingFlowPathProps - startSettingFlowPathProps), numPropsSet,
529 accTimeAddFlowEntries, numNewFlowEntries
530 );
531
532 // Each FlowEntries
533 final String strFlowId = flowPath.flowId().toString();
534 for ( long[] idFE_Time : flowEntryTimes ) {
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800535 log.error("Performance addFlowEntry(_,{},{})@addFlow -- FlowEntryTotal: {}",
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800536 strFlowId,
537 "0x" + Long.toHexString(idFE_Time[0]),
538 idFE_Time[1]);
539 }
540 }
541
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700542 return true;
543 }
544
545 /**
546 * Add a flow entry to the Network MAP.
547 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700548 * @param dbHandler the Graph Database handler to use.
549 * @param flowObj the corresponding Flow Path object for the Flow Entry.
550 * @param flowEntry the Flow Entry to install.
551 * @return the added Flow Entry object on success, otherwise null.
552 */
onlab-qa38805cd2013-12-06 20:08:54 -0800553 static IFlowEntry addFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700554 IFlowPath flowObj,
555 FlowEntry flowEntry) {
556 // Flow edges
557 // HeadFE (TODO)
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800558 long startAddFlowEntry = 0;
559 long endAddFlowEntry = 0;
560
561 long endSearchFlowEntry = 0;
562
563 long startCreateNewFlowEntry = 0;
564 long endCreateNewFlowEntry = 0;
565
566 long startSetProperties = 0;
567 long endSetProperties = 0;
568 int numProperties = 0;
569
570 long startSearchSwitch = 0;
571 long endSearchSwitch = 0;
572
573 long startAddEdgeToSwitch =0;
574 long endAddEdgeToSwitch =0;
575
576 long startSearchInPort = 0;
577 long endSearchInPort = 0;
578
579 long startAddEdgeToInPort =0;
580 long endAddEdgeToInPort =0;
581
582 long startSearchOutPort = 0;
583 long endSearchOutPort = 0;
584
585 long startAddEdgeToOutPort =0;
586 long endAddEdgeToOutPort =0;
587
588 long startAddEdgeBetweenFlowPath = 0;
589 long endAddEdgeBetweenFlowPath = 0;
590
591 if (measureONOSFlowEntryTimeProp) {
592 startAddFlowEntry = System.nanoTime();
593 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700594
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700595 IFlowEntry flowEntryObj = null;
596 boolean found = false;
597 try {
Yuta HIGUCHIc27a6c92014-01-07 11:51:11 -0800598 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
599 if (measureONOSFlowEntryTimeProp) {
600 endSearchFlowEntry = System.nanoTime();
601 }
602 if (flowEntryObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700603 found = true;
604 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800605 if (measureONOSFlowEntryTimeProp) {
606 startCreateNewFlowEntry = System.nanoTime();
607 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700608 flowEntryObj = dbHandler.newFlowEntry();
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800609 if (measureONOSFlowEntryTimeProp) {
610 endCreateNewFlowEntry = System.nanoTime();
611 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700612 }
613 } catch (Exception e) {
614 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800615 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700616 return null;
617 }
618 if (flowEntryObj == null) {
619 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800620 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700621 return null;
622 }
623
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800624 if (measureONOSFlowEntryTimeProp) {
625 startSetProperties = System.nanoTime();
626 }
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800627
Toshio Koidec71b7122014-01-13 15:16:53 -0800628 FlowEntryProperty flowProp = new FlowEntryProperty();
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800629
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700630 //
631 // Set the Flow Entry key:
632 // - flowEntry.flowEntryId()
633 //
Toshio Koide3f233542014-01-07 14:19:09 -0800634 flowProp.setFlowEntryId(flowEntry.flowEntryId().toString());
635 flowProp.setType("flow_entry");
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800636 if (measureONOSFlowEntryTimeProp) {
637 numProperties += 2;
638 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700639
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800640 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700641 // Set the Flow Entry Edges and attributes:
642 // - Switch edge
643 // - InPort edge
644 // - OutPort edge
645 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800646 // - flowEntry.idleTimeout()
647 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700648 // - flowEntry.dpid()
649 // - flowEntry.flowEntryUserState()
650 // - flowEntry.flowEntrySwitchState()
651 // - flowEntry.flowEntryErrorState()
652 // - flowEntry.matchInPort()
653 // - flowEntry.matchSrcMac()
654 // - flowEntry.matchDstMac()
655 // - flowEntry.matchEthernetFrameType()
656 // - flowEntry.matchVlanId()
657 // - flowEntry.matchVlanPriority()
658 // - flowEntry.matchSrcIPv4Net()
659 // - flowEntry.matchDstIPv4Net()
660 // - flowEntry.matchIpProto()
661 // - flowEntry.matchIpToS()
662 // - flowEntry.matchSrcTcpUdpPort()
663 // - flowEntry.matchDstTcpUdpPort()
664 // - flowEntry.actionOutputPort()
665 // - flowEntry.actions()
666 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800667 if (measureONOSFlowEntryTimeProp) {
668 startSearchSwitch = System.nanoTime();
669 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700670 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800671 if (measureONOSFlowEntryTimeProp) {
672 endSearchSwitch = System.nanoTime();
673 }
674
Toshio Koide3f233542014-01-07 14:19:09 -0800675 flowProp.setIdleTimeout(flowEntry.idleTimeout());
676 flowProp.setHardTimeout(flowEntry.hardTimeout());
677 flowProp.setSwitchDpid(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800678 if (measureONOSFlowEntryTimeProp) {
679 numProperties += 3;
680 }
681
682 if (measureONOSFlowEntryTimeProp) {
683 startAddEdgeToSwitch = System.nanoTime();
684 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700685 flowEntryObj.setSwitch(sw);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800686 if (measureONOSFlowEntryTimeProp) {
687 endAddEdgeToSwitch = System.nanoTime();
688 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700689 if (flowEntry.flowEntryMatch().matchInPort()) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800690 if (measureONOSFlowEntryTimeProp) {
691 startSearchInPort = System.nanoTime();
692 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700693 IPortObject inport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800694 dbHandler.searchPort(flowEntry.dpid().toString(),
695 flowEntry.flowEntryMatch().inPort().value());
696 if (measureONOSFlowEntryTimeProp) {
697 endSearchInPort = System.nanoTime();
698 }
699
Toshio Koide3f233542014-01-07 14:19:09 -0800700 flowProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800701 if (measureONOSFlowEntryTimeProp) {
702 ++numProperties;
703 }
704
705 if (measureONOSFlowEntryTimeProp) {
706 startAddEdgeToInPort = System.nanoTime();
707 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700708 flowEntryObj.setInPort(inport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800709 if (measureONOSFlowEntryTimeProp) {
710 endAddEdgeToInPort = System.nanoTime();
711 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700712 }
713 if (flowEntry.flowEntryMatch().matchSrcMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800714 flowProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800715 if (measureONOSFlowEntryTimeProp) {
716 ++numProperties;
717 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700718 }
719 if (flowEntry.flowEntryMatch().matchDstMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800720 flowProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800721 if (measureONOSFlowEntryTimeProp) {
722 ++numProperties;
723 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700724 }
725 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800726 flowProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800727 if (measureONOSFlowEntryTimeProp) {
728 ++numProperties;
729 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700730 }
731 if (flowEntry.flowEntryMatch().matchVlanId()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800732 flowProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800733 if (measureONOSFlowEntryTimeProp) {
734 ++numProperties;
735 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700736 }
737 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800738 flowProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800739 if (measureONOSFlowEntryTimeProp) {
740 ++numProperties;
741 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700742 }
743 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800744 flowProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800745 if (measureONOSFlowEntryTimeProp) {
746 ++numProperties;
747 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700748 }
749 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800750 flowProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800751 if (measureONOSFlowEntryTimeProp) {
752 ++numProperties;
753 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700754 }
755 if (flowEntry.flowEntryMatch().matchIpProto()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800756 flowProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800757 if (measureONOSFlowEntryTimeProp) {
758 ++numProperties;
759 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700760 }
761 if (flowEntry.flowEntryMatch().matchIpToS()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800762 flowProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800763 if (measureONOSFlowEntryTimeProp) {
764 ++numProperties;
765 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700766 }
767 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800768 flowProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800769 if (measureONOSFlowEntryTimeProp) {
770 ++numProperties;
771 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700772 }
773 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800774 flowProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800775 if (measureONOSFlowEntryTimeProp) {
776 ++numProperties;
777 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700778 }
779
780 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
781 if (fa.actionOutput() != null) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800782 if (measureONOSFlowEntryTimeProp) {
783 if ( startSearchOutPort != 0 ) log.error("Performance addFlowEntry(_,{},{}) -- Multiple output port action unexpected.", flowEntry.flowId(), flowEntry.flowEntryId());
784 startSearchOutPort = System.nanoTime();
785 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700786 IPortObject outport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800787 dbHandler.searchPort(flowEntry.dpid().toString(),
788 fa.actionOutput().port().value());
789 if (measureONOSFlowEntryTimeProp) {
790 endSearchOutPort = System.nanoTime();
791 }
792
Toshio Koide3f233542014-01-07 14:19:09 -0800793 flowProp.setActionOutputPort(fa.actionOutput().port().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800794 if (measureONOSFlowEntryTimeProp) {
795 ++numProperties;
796 }
797
798 if (measureONOSFlowEntryTimeProp) {
799 startAddEdgeToOutPort = System.nanoTime();
800 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700801 flowEntryObj.setOutPort(outport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800802 if (measureONOSFlowEntryTimeProp) {
803 endAddEdgeToOutPort = System.nanoTime();
804 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700805 }
806 }
807 if (! flowEntry.flowEntryActions().isEmpty()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800808 flowProp.setActions(flowEntry.flowEntryActions().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800809 if (measureONOSFlowEntryTimeProp) {
810 ++numProperties;
811 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700812 }
813
814 // TODO: Hacks with hard-coded state names!
815 if (found)
Toshio Koide3f233542014-01-07 14:19:09 -0800816 flowProp.setUserState("FE_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700817 else
Toshio Koide3f233542014-01-07 14:19:09 -0800818 flowProp.setUserState("FE_USER_ADD");
819 flowProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800820 if (measureONOSFlowEntryTimeProp) {
821 numProperties += 2;
822 }
Toshio Koidec71b7122014-01-13 15:16:53 -0800823 flowProp.commitProperties(dbHandler, flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700824 //
825 // TODO: Take care of the FlowEntryErrorState.
826 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800827 if (measureONOSFlowEntryTimeProp) {
828 endSetProperties = System.nanoTime();
829 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700830
831 // Flow Entries edges:
832 // Flow
833 // NextFE (TODO)
834 if (! found) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800835 if (measureONOSFlowEntryTimeProp) {
836 startAddEdgeBetweenFlowPath = System.nanoTime();
837 }
Toshio Koidec71b7122014-01-13 15:16:53 -0800838 //flowObj.addFlowEntry(flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700839 flowEntryObj.setFlow(flowObj);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800840 if (measureONOSFlowEntryTimeProp) {
841 endAddEdgeBetweenFlowPath = System.nanoTime();
842 }
843 }
844 if (measureONOSFlowEntryTimeProp) {
845 endAddFlowEntry = System.nanoTime();
846
847 log.error("Performance addFlowEntry(_,{},{}) -- "
848 + "GrandTotal: {} "
849 + "SearchExistingFE: {} "
850 + "CreateNewFE: {} "
851 + "SetProp+Edge: {} #Props: {} "
852 + "SearchSwitch: {} "
853 + "AddEdgeToSwitch: {} "
854 + "SearchInPort: {} "
855 + "AddEdgeToInPort: {} "
856 + "SearchOutPort: {} "
857 + "AddEdgeToOutPort: {} "
858 + "AddEdgeBetweenFlowPath: {} "
859 , flowEntry.flowId(), flowEntry.flowEntryId()
860 , endAddFlowEntry - startAddFlowEntry
861 , endSearchFlowEntry - startAddFlowEntry
862 , endCreateNewFlowEntry - startCreateNewFlowEntry
863 , endSetProperties - startSetProperties, numProperties
864 , endSearchSwitch - startSearchSwitch
865 , endAddEdgeToSwitch - startAddEdgeToSwitch
866 , endSearchInPort - startSearchInPort
867 , endAddEdgeToInPort - startAddEdgeToInPort
868 , endSearchOutPort - startSearchOutPort
869 , endAddEdgeToOutPort - startAddEdgeToOutPort
870 , endAddEdgeBetweenFlowPath - startAddEdgeBetweenFlowPath
871 );
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700872 }
873
874 return flowEntryObj;
875 }
876
877 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700878 * Delete a flow entry from the Network MAP.
879 *
880 * @param dbHandler the Graph Database handler to use.
881 * @param flowObj the corresponding Flow Path object for the Flow Entry.
882 * @param flowEntry the Flow Entry to delete.
883 * @return true on success, otherwise false.
884 */
yoshitomob292c622013-11-23 14:35:58 -0800885 static boolean deleteFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700886 IFlowPath flowObj,
887 FlowEntry flowEntry) {
888 IFlowEntry flowEntryObj = null;
889 try {
890 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
891 } catch (Exception e) {
892 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800893 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700894 return false;
895 }
896 //
897 // TODO: Don't print an error for now, because multiple controller
898 // instances might be deleting the same flow entry.
899 //
900 /*
901 if (flowEntryObj == null) {
902 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800903 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700904 return false;
905 }
906 */
907 if (flowEntryObj == null)
908 return true;
909
910 flowObj.removeFlowEntry(flowEntryObj);
911 dbHandler.removeFlowEntry(flowEntryObj);
912 return true;
913 }
914
915 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700916 * Delete all previously added flows.
917 *
918 * @param dbHandler the Graph Database handler to use.
919 * @return true on success, otherwise false.
920 */
yoshitomob292c622013-11-23 14:35:58 -0800921 static boolean deleteAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700922 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
923 for (IFlowPath flowPathObj : allFlowPaths) {
924 if (flowPathObj == null)
925 continue;
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800926 deleteIFlowPath(dbHandler, flowPathObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700927 }
Yuta HIGUCHI0cc22372014-01-13 14:54:00 -0800928 dbHandler.commit();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700929
930 return true;
931 }
932
933 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800934 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700935 *
936 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800937 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700938 * @return true on success, otherwise false.
939 */
yoshitomob292c622013-11-23 14:35:58 -0800940 static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700941 IFlowPath flowObj = null;
942 try {
943 flowObj = dbHandler.searchFlowPath(flowId);
944 } catch (Exception e) {
945 // TODO: handle exceptions
946 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800947 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700948 return false;
949 }
950 if (flowObj == null) {
951 dbHandler.commit();
952 return true; // OK: No such flow
953 }
954
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800955 deleteIFlowPath(dbHandler, flowObj);
Yuta HIGUCHI0cc22372014-01-13 14:54:00 -0800956 dbHandler.commit();
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800957
958 return true;
959 }
960
961 private static void deleteIFlowPath(DBOperation dbHandler, IFlowPath flowObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700962 //
963 // Remove all Flow Entries
964 //
965 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
966 for (IFlowEntry flowEntryObj : flowEntries) {
967 flowObj.removeFlowEntry(flowEntryObj);
968 dbHandler.removeFlowEntry(flowEntryObj);
969 }
970 // Remove the Flow itself
971 dbHandler.removeFlowPath(flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700972 }
973
974 /**
975 * Get a previously added flow.
976 *
977 * @param dbHandler the Graph Database handler to use.
978 * @param flowId the Flow ID of the flow to get.
979 * @return the Flow Path if found, otherwise null.
980 */
yoshitomob292c622013-11-23 14:35:58 -0800981 static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700982 IFlowPath flowObj = null;
983 try {
984 flowObj = dbHandler.searchFlowPath(flowId);
985 } catch (Exception e) {
986 // TODO: handle exceptions
987 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800988 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700989 return null;
990 }
991 if (flowObj == null) {
992 dbHandler.commit();
993 return null; // Flow not found
994 }
995
996 //
997 // Extract the Flow state
998 //
999 FlowPath flowPath = extractFlowPath(flowObj);
1000 dbHandler.commit();
1001
1002 return flowPath;
1003 }
1004
1005 /**
1006 * Get all installed flows by all installers.
1007 *
1008 * @param dbHandler the Graph Database handler to use.
1009 * @return the Flow Paths if found, otherwise null.
1010 */
yoshitomob292c622013-11-23 14:35:58 -08001011 static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001012 Iterable<IFlowPath> flowPathsObj = null;
1013 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
1014
1015 try {
1016 flowPathsObj = dbHandler.getAllFlowPaths();
1017 } catch (Exception e) {
1018 // TODO: handle exceptions
1019 dbHandler.rollback();
1020 log.error(":getAllFlowPaths failed");
1021 return flowPaths;
1022 }
1023 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
1024 dbHandler.commit();
1025 return flowPaths; // No Flows found
1026 }
1027
1028 for (IFlowPath flowObj : flowPathsObj) {
1029 //
1030 // Extract the Flow state
1031 //
1032 FlowPath flowPath = extractFlowPath(flowObj);
1033 if (flowPath != null)
1034 flowPaths.add(flowPath);
1035 }
1036
1037 dbHandler.commit();
1038
1039 return flowPaths;
1040 }
1041
1042 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001043 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
1044 *
1045 * @param flowObj the object to extract the Flow Path State from.
1046 * @return the extracted Flow Path State.
1047 */
1048 private static FlowPath extractFlowPath(IFlowPath flowObj) {
1049 //
1050 // Extract the Flow state
1051 //
Toshio Koidea9b25142014-01-10 01:15:57 -08001052 log.info("extractFlowPath: start");
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001053 String flowIdStr;
1054 String installerIdStr;
1055 String flowPathType;
1056 String flowPathUserState;
1057 Long flowPathFlags;
1058 Integer idleTimeout;
1059 Integer hardTimeout;
1060 String srcSwitchStr;
1061 Short srcPortShort;
1062 String dstSwitchStr;
1063 Short dstPortShort;
1064
1065 if ( flowObj.asVertex() instanceof RamCloudVertex ) {
1066 RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
1067 Map<String,Object> propMap = v.getProperties();
1068
1069 flowIdStr = (String) propMap.get("flow_id");
1070 installerIdStr = (String) propMap.get("installer_id");
1071 flowPathType = (String) propMap.get("flow_path_type");
1072 flowPathUserState = (String) propMap.get("user_state");
1073 flowPathFlags = (Long)propMap.get("flow_path_flags");
1074 idleTimeout = (Integer) propMap.get("idle_timeout");
1075 hardTimeout = (Integer) propMap.get("hard_timeout");
1076 srcSwitchStr = (String) propMap.get("src_switch");
1077 srcPortShort = (Short)propMap.get("src_port");
1078 dstSwitchStr = (String) propMap.get("dst_switch");
1079 dstPortShort = (Short)propMap.get("dst_port");
1080 } else {
1081 flowIdStr = flowObj.getFlowId();
1082 installerIdStr = flowObj.getInstallerId();
1083 flowPathType = flowObj.getFlowPathType();
1084 flowPathUserState = flowObj.getFlowPathUserState();
1085 flowPathFlags = flowObj.getFlowPathFlags();
1086 idleTimeout = flowObj.getIdleTimeout();
1087 hardTimeout = flowObj.getHardTimeout();
1088 srcSwitchStr = flowObj.getSrcSwitch();
1089 srcPortShort = flowObj.getSrcPort();
1090 dstSwitchStr = flowObj.getDstSwitch();
1091 dstPortShort = flowObj.getDstPort();
1092 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001093
1094 if ((flowIdStr == null) ||
1095 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -07001096 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -07001097 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001098 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001099 (idleTimeout == null) ||
1100 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001101 (srcSwitchStr == null) ||
1102 (srcPortShort == null) ||
1103 (dstSwitchStr == null) ||
1104 (dstPortShort == null)) {
Toshio Koidea9b25142014-01-10 01:15:57 -08001105 // TODO: A work-around, because of some bogus database objects
1106 log.error("extractFlowPath: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001107 return null;
1108 }
1109
1110 FlowPath flowPath = new FlowPath();
1111 flowPath.setFlowId(new FlowId(flowIdStr));
1112 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -07001113 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -07001114 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001115 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001116 flowPath.setIdleTimeout(idleTimeout);
1117 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001118 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
1119 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
1120 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
1121 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
1122 //
1123 // Extract the match conditions common for all Flow Entries
1124 //
1125 {
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001126 FlowEntryMatch match = extractMatch(flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001127
1128 flowPath.setFlowEntryMatch(match);
1129 }
1130 //
1131 // Extract the actions for the first Flow Entry
1132 //
1133 {
1134 String actionsStr = flowObj.getActions();
1135 if (actionsStr != null) {
1136 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
1137 flowPath.setFlowEntryActions(flowEntryActions);
1138 }
1139 }
1140
1141 //
1142 // Extract all Flow Entries
1143 //
1144 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
1145 for (IFlowEntry flowEntryObj : flowEntries) {
1146 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
1147 if (flowEntry == null)
1148 continue;
1149 flowPath.dataPath().flowEntries().add(flowEntry);
1150 }
1151
Toshio Koidea9b25142014-01-10 01:15:57 -08001152 log.info("extractFlowPath: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001153 return flowPath;
1154 }
1155
1156 /**
1157 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
1158 *
1159 * @param flowEntryObj the object to extract the Flow Entry State from.
1160 * @return the extracted Flow Entry State.
1161 */
Brian O'Connora8e49802013-10-30 20:49:59 -07001162 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Toshio Koidea9b25142014-01-10 01:15:57 -08001163 log.info("extractFlowEntry: start");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001164 IFlowPath flowObj = flowEntryObj.getFlow();
Toshio Koidea9b25142014-01-10 01:15:57 -08001165 if (flowObj == null) {
1166 log.error("extractFlowEntry: no flowPath exists");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001167 return null;
Toshio Koidea9b25142014-01-10 01:15:57 -08001168 }
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001169
1170 String flowIdStr = flowObj.getFlowId();
1171 //
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001172 String flowEntryIdStr;
1173 Integer idleTimeout;
1174 Integer hardTimeout;
1175 String switchDpidStr;
1176 String userState;
1177 String switchState;
1178 if ( flowEntryObj.asVertex() instanceof RamCloudVertex ) {
1179 RamCloudVertex v = (RamCloudVertex)flowEntryObj.asVertex();
1180 Map<String,Object> propMap = v.getProperties();
1181
1182 flowEntryIdStr = (String) propMap.get("flow_entry_id");
1183 idleTimeout = (Integer) propMap.get("idle_timeout");
1184 hardTimeout = (Integer) propMap.get("hard_timeout");
1185 switchDpidStr = (String) propMap.get("switch_dpid");
1186 userState = (String) propMap.get("user_state");
1187 switchState = (String) propMap.get("switch_state");
1188 } else {
1189 flowEntryIdStr = flowEntryObj.getFlowEntryId();
1190 idleTimeout = flowEntryObj.getIdleTimeout();
1191 hardTimeout = flowEntryObj.getHardTimeout();
1192 switchDpidStr = flowEntryObj.getSwitchDpid();
1193 userState = flowEntryObj.getUserState();
1194 switchState = flowEntryObj.getSwitchState();
1195 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001196
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001197 if ((flowIdStr == null) ||
1198 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001199 (idleTimeout == null) ||
1200 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001201 (switchDpidStr == null) ||
1202 (userState == null) ||
1203 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -07001204 // TODO: A work-around, because of some bogus database objects
Toshio Koidea9b25142014-01-10 01:15:57 -08001205 log.error("extractFlowEntry: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001206 return null;
1207 }
1208
1209 FlowEntry flowEntry = new FlowEntry();
1210 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001211 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001212 flowEntry.setDpid(new Dpid(switchDpidStr));
yoshia97632b2013-12-17 15:46:08 -08001213 flowEntry.setIdleTimeout(idleTimeout);
1214 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001215
1216 //
1217 // Extract the match conditions
1218 //
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001219 FlowEntryMatch match = extractMatch(flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001220 flowEntry.setFlowEntryMatch(match);
1221
1222 //
1223 // Extract the actions
1224 //
1225 FlowEntryActions actions = new FlowEntryActions();
1226 String actionsStr = flowEntryObj.getActions();
1227 if (actionsStr != null)
1228 actions = new FlowEntryActions(actionsStr);
1229 flowEntry.setFlowEntryActions(actions);
1230 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
1231 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
1232 //
1233 // TODO: Take care of FlowEntryErrorState.
1234 //
Toshio Koidea9b25142014-01-10 01:15:57 -08001235 log.info("extractFlowEntry: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001236 return flowEntry;
1237 }
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001238
1239 /**
1240 * Extract FlowEntryMatch from IFlowPath or IFlowEntry
1241 * @param flowObj : either IFlowPath or IFlowEntry
1242 * @return extracted Match info
1243 */
1244 private static FlowEntryMatch extractMatch(IBaseObject flowObj) {
1245 FlowEntryMatch match = new FlowEntryMatch();
1246
1247 Short matchInPort = null; // Only for IFlowEntry
1248 String matchSrcMac = null;
1249 String matchDstMac = null;
1250 Short matchEthernetFrameType = null;
1251 Short matchVlanId = null;
1252 Byte matchVlanPriority = null;
1253 String matchSrcIPv4Net = null;
1254 String matchDstIPv4Net = null;
1255 Byte matchIpProto = null;
1256 Byte matchIpToS = null;
1257 Short matchSrcTcpUdpPort = null;
1258 Short matchDstTcpUdpPort = null;
1259
1260 if ( flowObj.asVertex() instanceof RamCloudVertex ) {
1261 RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
1262 Map<String,Object> propMap = v.getProperties();
1263 matchInPort = (Short) propMap.get("matchInPort");
1264 matchSrcMac = (String) propMap.get("matchSrcMac");
1265 matchDstMac = (String) propMap.get("matchDstMac");
1266 matchEthernetFrameType = (Short) propMap.get("matchEthernetFrameType");
1267 matchVlanId = (Short) propMap.get("matchVlanId");
1268 matchVlanPriority = (Byte) propMap.get("matchVlanPriority");
1269 matchSrcIPv4Net = (String) propMap.get("matchSrcIPv4Net");
1270 matchDstIPv4Net = (String) propMap.get("matchDstIPv4Net");
1271 matchIpProto = (Byte) propMap.get("matchIpProto");
1272 matchIpToS = (Byte) propMap.get("matchIpToS");
1273 matchSrcTcpUdpPort = (Short) propMap.get("matchSrcTcpUdpPort");
1274 matchDstTcpUdpPort = (Short) propMap.get("matchDstTcpUdpPort");
1275 } else {
1276 if (flowObj instanceof IFlowEntry ){
1277 IFlowEntry flowEntry = (IFlowEntry) flowObj;
1278 matchInPort = flowEntry.getMatchInPort();
1279 matchSrcMac = flowEntry.getMatchSrcMac();
1280 matchDstMac = flowEntry.getMatchDstMac();
1281 matchEthernetFrameType = flowEntry.getMatchEthernetFrameType();
1282 matchVlanId = flowEntry.getMatchVlanId();
1283 matchVlanPriority = flowEntry.getMatchVlanPriority();
1284 matchSrcIPv4Net = flowEntry.getMatchSrcIPv4Net();
1285 matchDstIPv4Net = flowEntry.getMatchDstIPv4Net();
1286 matchIpProto = flowEntry.getMatchIpProto();
1287 matchIpToS = flowEntry.getMatchIpToS();
1288 matchSrcTcpUdpPort = flowEntry.getMatchSrcTcpUdpPort();
1289 matchDstTcpUdpPort = flowEntry.getMatchDstTcpUdpPort();
1290 } else if(flowObj instanceof IFlowPath) {
1291 IFlowPath flowPath = (IFlowPath) flowObj;
1292 matchSrcMac = flowPath.getMatchSrcMac();
1293 matchDstMac = flowPath.getMatchDstMac();
1294 matchEthernetFrameType = flowPath.getMatchEthernetFrameType();
1295 matchVlanId = flowPath.getMatchVlanId();
1296 matchVlanPriority = flowPath.getMatchVlanPriority();
1297 matchSrcIPv4Net = flowPath.getMatchSrcIPv4Net();
1298 matchDstIPv4Net = flowPath.getMatchDstIPv4Net();
1299 matchIpProto = flowPath.getMatchIpProto();
1300 matchIpToS = flowPath.getMatchIpToS();
1301 matchSrcTcpUdpPort = flowPath.getMatchSrcTcpUdpPort();
1302 matchDstTcpUdpPort = flowPath.getMatchDstTcpUdpPort();
1303 }
1304 }
1305
1306 if (matchInPort != null)
1307 match.enableInPort(new Port(matchInPort));
1308 if (matchSrcMac != null)
1309 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
1310 if (matchDstMac != null)
1311 match.enableDstMac(MACAddress.valueOf(matchDstMac));
1312 if (matchEthernetFrameType != null)
1313 match.enableEthernetFrameType(matchEthernetFrameType);
1314 if (matchVlanId != null)
1315 match.enableVlanId(matchVlanId);
1316 if (matchVlanPriority != null)
1317 match.enableVlanPriority(matchVlanPriority);
1318 if (matchSrcIPv4Net != null)
1319 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
1320 if (matchDstIPv4Net != null)
1321 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
1322 if (matchIpProto != null)
1323 match.enableIpProto(matchIpProto);
1324 if (matchIpToS != null)
1325 match.enableIpToS(matchIpToS);
1326 if (matchSrcTcpUdpPort != null)
1327 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
1328 if (matchDstTcpUdpPort != null)
1329 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
1330 return match;
1331 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001332}