blob: da407ab1a7ea7fdd93e6de36b42e512decba2caa [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;
7import java.util.List;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07008
9import net.floodlightcontroller.util.MACAddress;
10
11import net.onrc.onos.graph.GraphDBOperation;
12
13import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
14import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
15import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
16import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
17import net.onrc.onos.ofcontroller.util.*;
18
19import org.slf4j.Logger;
20import org.slf4j.LoggerFactory;
21
22/**
23 * Class for performing Flow-related operations on the Database.
24 */
Pavlin Radoslavov6bfaea62013-12-03 14:55:57 -080025public class FlowDatabaseOperation {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070026 private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070027
28 /**
29 * Add a flow.
30 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070031 * @param dbHandler the Graph Database handler to use.
32 * @param flowPath the Flow Path to install.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070033 * @return true on success, otherwise false.
34 */
Pavlin Radoslavov051abb42013-12-05 17:24:50 -080035 static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070036 IFlowPath flowObj = null;
37 boolean found = false;
38 try {
39 if ((flowObj = dbHandler.searchFlowPath(flowPath.flowId())) != null) {
40 found = true;
41 } else {
42 flowObj = dbHandler.newFlowPath();
43 }
44 } catch (Exception e) {
45 dbHandler.rollback();
46
47 StringWriter sw = new StringWriter();
48 e.printStackTrace(new PrintWriter(sw));
49 String stacktrace = sw.toString();
50
51 log.error(":addFlow FlowId:{} failed: {}",
52 flowPath.flowId().toString(),
53 stacktrace);
54 return false;
55 }
56 if (flowObj == null) {
57 log.error(":addFlow FlowId:{} failed: Flow object not created",
58 flowPath.flowId().toString());
59 dbHandler.rollback();
60 return false;
61 }
62
63 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080064 // Remove the old Flow Entries
65 //
66 if (found) {
67 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
68 LinkedList<IFlowEntry> deleteFlowEntries =
69 new LinkedList<IFlowEntry>();
70 for (IFlowEntry flowEntryObj : flowEntries)
71 deleteFlowEntries.add(flowEntryObj);
72 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
73 flowObj.removeFlowEntry(flowEntryObj);
74 dbHandler.removeFlowEntry(flowEntryObj);
75 }
76 }
77
78 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070079 // Set the Flow key:
80 // - flowId
81 //
82 flowObj.setFlowId(flowPath.flowId().toString());
83 flowObj.setType("flow");
84
85 //
86 // Set the Flow attributes:
87 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -070088 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -070089 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070090 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -080091 // - flowPath.idleTimeout()
92 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070093 // - flowPath.dataPath().srcPort()
94 // - flowPath.dataPath().dstPort()
95 // - flowPath.matchSrcMac()
96 // - flowPath.matchDstMac()
97 // - flowPath.matchEthernetFrameType()
98 // - flowPath.matchVlanId()
99 // - flowPath.matchVlanPriority()
100 // - flowPath.matchSrcIPv4Net()
101 // - flowPath.matchDstIPv4Net()
102 // - flowPath.matchIpProto()
103 // - flowPath.matchIpToS()
104 // - flowPath.matchSrcTcpUdpPort()
105 // - flowPath.matchDstTcpUdpPort()
106 // - flowPath.flowEntryActions()
107 //
108 flowObj.setInstallerId(flowPath.installerId().toString());
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700109 flowObj.setFlowPathType(flowPath.flowPathType().toString());
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700110 flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700111 flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800112 flowObj.setIdleTimeout(flowPath.idleTimeout());
113 flowObj.setHardTimeout(flowPath.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700114 flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
115 flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
116 flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
117 flowObj.setDstPort(flowPath.dataPath().dstPort().port().value());
118 if (flowPath.flowEntryMatch().matchSrcMac()) {
119 flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
120 }
121 if (flowPath.flowEntryMatch().matchDstMac()) {
122 flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
123 }
124 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
125 flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
126 }
127 if (flowPath.flowEntryMatch().matchVlanId()) {
128 flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
129 }
130 if (flowPath.flowEntryMatch().matchVlanPriority()) {
131 flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
132 }
133 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
134 flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
135 }
136 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
137 flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
138 }
139 if (flowPath.flowEntryMatch().matchIpProto()) {
140 flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
141 }
142 if (flowPath.flowEntryMatch().matchIpToS()) {
143 flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
144 }
145 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
146 flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
147 }
148 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
149 flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
150 }
151 if (! flowPath.flowEntryActions().actions().isEmpty()) {
152 flowObj.setActions(flowPath.flowEntryActions().toString());
153 }
Pavlin Radoslavovbcc86ef2013-10-26 12:06:25 -0700154 flowObj.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700155
156 if (found)
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700157 flowObj.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700158 else
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700159 flowObj.setFlowPathUserState("FP_USER_ADD");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700160
161 // Flow edges:
162 // HeadFE
163
164
165 //
166 // Flow Entries:
167 // flowPath.dataPath().flowEntries()
168 //
169 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800170 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
171 continue; // Skip: all Flow Entries were deleted earlier
172
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800173 if (addFlowEntry(dbHandler, flowObj, flowEntry) == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700174 dbHandler.rollback();
175 return false;
176 }
177 }
178 dbHandler.commit();
179
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700180 return true;
181 }
182
183 /**
184 * Add a flow entry to the Network MAP.
185 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700186 * @param dbHandler the Graph Database handler to use.
187 * @param flowObj the corresponding Flow Path object for the Flow Entry.
188 * @param flowEntry the Flow Entry to install.
189 * @return the added Flow Entry object on success, otherwise null.
190 */
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800191 static IFlowEntry addFlowEntry(GraphDBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700192 IFlowPath flowObj,
193 FlowEntry flowEntry) {
194 // Flow edges
195 // HeadFE (TODO)
196
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700197 IFlowEntry flowEntryObj = null;
198 boolean found = false;
199 try {
200 if ((flowEntryObj =
201 dbHandler.searchFlowEntry(flowEntry.flowEntryId())) != null) {
202 found = true;
203 } else {
204 flowEntryObj = dbHandler.newFlowEntry();
205 }
206 } catch (Exception e) {
207 log.error(":addFlow FlowEntryId:{} failed",
208 flowEntry.flowEntryId().toString());
209 return null;
210 }
211 if (flowEntryObj == null) {
212 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
213 flowEntry.flowEntryId().toString());
214 return null;
215 }
216
217 //
218 // Set the Flow Entry key:
219 // - flowEntry.flowEntryId()
220 //
221 flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
222 flowEntryObj.setType("flow_entry");
223
224 //
225 // Set the Flow Entry Edges and attributes:
226 // - Switch edge
227 // - InPort edge
228 // - OutPort edge
229 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800230 // - flowEntry.idleTimeout()
231 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700232 // - flowEntry.dpid()
233 // - flowEntry.flowEntryUserState()
234 // - flowEntry.flowEntrySwitchState()
235 // - flowEntry.flowEntryErrorState()
236 // - flowEntry.matchInPort()
237 // - flowEntry.matchSrcMac()
238 // - flowEntry.matchDstMac()
239 // - flowEntry.matchEthernetFrameType()
240 // - flowEntry.matchVlanId()
241 // - flowEntry.matchVlanPriority()
242 // - flowEntry.matchSrcIPv4Net()
243 // - flowEntry.matchDstIPv4Net()
244 // - flowEntry.matchIpProto()
245 // - flowEntry.matchIpToS()
246 // - flowEntry.matchSrcTcpUdpPort()
247 // - flowEntry.matchDstTcpUdpPort()
248 // - flowEntry.actionOutputPort()
249 // - flowEntry.actions()
250 //
251 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800252 flowEntryObj.setIdleTimeout(flowEntry.idleTimeout());
253 flowEntryObj.setHardTimeout(flowEntry.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700254 flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
255 flowEntryObj.setSwitch(sw);
256 if (flowEntry.flowEntryMatch().matchInPort()) {
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800257 IPortObject inport =
258 dbHandler.searchPort(flowEntry.dpid().toString(),
259 flowEntry.flowEntryMatch().inPort().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700260 flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800261 flowEntryObj.setInPort(inport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700262 }
263 if (flowEntry.flowEntryMatch().matchSrcMac()) {
264 flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
265 }
266 if (flowEntry.flowEntryMatch().matchDstMac()) {
267 flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
268 }
269 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
270 flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
271 }
272 if (flowEntry.flowEntryMatch().matchVlanId()) {
273 flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
274 }
275 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
276 flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
277 }
278 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
279 flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
280 }
281 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
282 flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
283 }
284 if (flowEntry.flowEntryMatch().matchIpProto()) {
285 flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
286 }
287 if (flowEntry.flowEntryMatch().matchIpToS()) {
288 flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
289 }
290 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
291 flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
292 }
293 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
294 flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
295 }
296
297 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
298 if (fa.actionOutput() != null) {
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800299 IPortObject outport =
300 dbHandler.searchPort(flowEntry.dpid().toString(),
301 fa.actionOutput().port().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700302 flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800303 flowEntryObj.setOutPort(outport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700304 }
305 }
306 if (! flowEntry.flowEntryActions().isEmpty()) {
307 flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
308 }
309
310 // TODO: Hacks with hard-coded state names!
311 if (found)
312 flowEntryObj.setUserState("FE_USER_MODIFY");
313 else
314 flowEntryObj.setUserState("FE_USER_ADD");
Pavlin Radoslavovebc8b192013-10-29 15:35:35 -0700315 flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700316 //
317 // TODO: Take care of the FlowEntryErrorState.
318 //
319
320 // Flow Entries edges:
321 // Flow
322 // NextFE (TODO)
323 if (! found) {
324 flowObj.addFlowEntry(flowEntryObj);
325 flowEntryObj.setFlow(flowObj);
326 }
327
328 return flowEntryObj;
329 }
330
331 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700332 * Delete a flow entry from the Network MAP.
333 *
334 * @param dbHandler the Graph Database handler to use.
335 * @param flowObj the corresponding Flow Path object for the Flow Entry.
336 * @param flowEntry the Flow Entry to delete.
337 * @return true on success, otherwise false.
338 */
339 static boolean deleteFlowEntry(GraphDBOperation dbHandler,
340 IFlowPath flowObj,
341 FlowEntry flowEntry) {
342 IFlowEntry flowEntryObj = null;
343 try {
344 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
345 } catch (Exception e) {
346 log.error(":deleteFlowEntry FlowEntryId:{} failed",
347 flowEntry.flowEntryId().toString());
348 return false;
349 }
350 //
351 // TODO: Don't print an error for now, because multiple controller
352 // instances might be deleting the same flow entry.
353 //
354 /*
355 if (flowEntryObj == null) {
356 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
357 flowEntry.flowEntryId().toString());
358 return false;
359 }
360 */
361 if (flowEntryObj == null)
362 return true;
363
364 flowObj.removeFlowEntry(flowEntryObj);
365 dbHandler.removeFlowEntry(flowEntryObj);
366 return true;
367 }
368
369 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700370 * Delete all previously added flows.
371 *
372 * @param dbHandler the Graph Database handler to use.
373 * @return true on success, otherwise false.
374 */
375 static boolean deleteAllFlows(GraphDBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700376 List<FlowId> allFlowIds = new LinkedList<FlowId>();
377
378 // Get all Flow IDs
379 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
380 for (IFlowPath flowPathObj : allFlowPaths) {
381 if (flowPathObj == null)
382 continue;
383 String flowIdStr = flowPathObj.getFlowId();
384 if (flowIdStr == null)
385 continue;
386 FlowId flowId = new FlowId(flowIdStr);
387 allFlowIds.add(flowId);
388 }
389
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800390 // Delete all flows one-by-one
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700391 for (FlowId flowId : allFlowIds) {
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800392 deleteFlow(dbHandler, flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700393 }
394
395 return true;
396 }
397
398 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800399 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700400 *
401 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800402 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700403 * @return true on success, otherwise false.
404 */
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800405 static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700406 IFlowPath flowObj = null;
407 try {
408 flowObj = dbHandler.searchFlowPath(flowId);
409 } catch (Exception e) {
410 // TODO: handle exceptions
411 dbHandler.rollback();
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800412 log.error(":deleteFlow FlowId:{} failed", flowId.toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700413 return false;
414 }
415 if (flowObj == null) {
416 dbHandler.commit();
417 return true; // OK: No such flow
418 }
419
420 //
421 // Remove all Flow Entries
422 //
423 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
424 for (IFlowEntry flowEntryObj : flowEntries) {
425 flowObj.removeFlowEntry(flowEntryObj);
426 dbHandler.removeFlowEntry(flowEntryObj);
427 }
428 // Remove the Flow itself
429 dbHandler.removeFlowPath(flowObj);
430 dbHandler.commit();
431
432 return true;
433 }
434
435 /**
436 * Get a previously added flow.
437 *
438 * @param dbHandler the Graph Database handler to use.
439 * @param flowId the Flow ID of the flow to get.
440 * @return the Flow Path if found, otherwise null.
441 */
442 static FlowPath getFlow(GraphDBOperation dbHandler, FlowId flowId) {
443 IFlowPath flowObj = null;
444 try {
445 flowObj = dbHandler.searchFlowPath(flowId);
446 } catch (Exception e) {
447 // TODO: handle exceptions
448 dbHandler.rollback();
449 log.error(":getFlow FlowId:{} failed", flowId.toString());
450 return null;
451 }
452 if (flowObj == null) {
453 dbHandler.commit();
454 return null; // Flow not found
455 }
456
457 //
458 // Extract the Flow state
459 //
460 FlowPath flowPath = extractFlowPath(flowObj);
461 dbHandler.commit();
462
463 return flowPath;
464 }
465
466 /**
467 * Get all installed flows by all installers.
468 *
469 * @param dbHandler the Graph Database handler to use.
470 * @return the Flow Paths if found, otherwise null.
471 */
472 static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler) {
473 Iterable<IFlowPath> flowPathsObj = null;
474 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
475
476 try {
477 flowPathsObj = dbHandler.getAllFlowPaths();
478 } catch (Exception e) {
479 // TODO: handle exceptions
480 dbHandler.rollback();
481 log.error(":getAllFlowPaths failed");
482 return flowPaths;
483 }
484 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
485 dbHandler.commit();
486 return flowPaths; // No Flows found
487 }
488
489 for (IFlowPath flowObj : flowPathsObj) {
490 //
491 // Extract the Flow state
492 //
493 FlowPath flowPath = extractFlowPath(flowObj);
494 if (flowPath != null)
495 flowPaths.add(flowPath);
496 }
497
498 dbHandler.commit();
499
500 return flowPaths;
501 }
502
503 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700504 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
505 *
506 * @param flowObj the object to extract the Flow Path State from.
507 * @return the extracted Flow Path State.
508 */
509 private static FlowPath extractFlowPath(IFlowPath flowObj) {
510 //
511 // Extract the Flow state
512 //
513 String flowIdStr = flowObj.getFlowId();
514 String installerIdStr = flowObj.getInstallerId();
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700515 String flowPathType = flowObj.getFlowPathType();
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700516 String flowPathUserState = flowObj.getFlowPathUserState();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700517 Long flowPathFlags = flowObj.getFlowPathFlags();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800518 Integer idleTimeout = flowObj.getIdleTimeout();
519 Integer hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700520 String srcSwitchStr = flowObj.getSrcSwitch();
521 Short srcPortShort = flowObj.getSrcPort();
522 String dstSwitchStr = flowObj.getDstSwitch();
523 Short dstPortShort = flowObj.getDstPort();
524
525 if ((flowIdStr == null) ||
526 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700527 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700528 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700529 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800530 (idleTimeout == null) ||
531 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700532 (srcSwitchStr == null) ||
533 (srcPortShort == null) ||
534 (dstSwitchStr == null) ||
535 (dstPortShort == null)) {
536 // TODO: A work-around, becauuse of some bogus database objects
537 return null;
538 }
539
540 FlowPath flowPath = new FlowPath();
541 flowPath.setFlowId(new FlowId(flowIdStr));
542 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700543 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700544 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700545 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800546 flowPath.setIdleTimeout(idleTimeout);
547 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700548 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
549 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
550 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
551 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
552 //
553 // Extract the match conditions common for all Flow Entries
554 //
555 {
556 FlowEntryMatch match = new FlowEntryMatch();
557 String matchSrcMac = flowObj.getMatchSrcMac();
558 if (matchSrcMac != null)
559 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
560 String matchDstMac = flowObj.getMatchDstMac();
561 if (matchDstMac != null)
562 match.enableDstMac(MACAddress.valueOf(matchDstMac));
563 Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
564 if (matchEthernetFrameType != null)
565 match.enableEthernetFrameType(matchEthernetFrameType);
566 Short matchVlanId = flowObj.getMatchVlanId();
567 if (matchVlanId != null)
568 match.enableVlanId(matchVlanId);
569 Byte matchVlanPriority = flowObj.getMatchVlanPriority();
570 if (matchVlanPriority != null)
571 match.enableVlanPriority(matchVlanPriority);
572 String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
573 if (matchSrcIPv4Net != null)
574 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
575 String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
576 if (matchDstIPv4Net != null)
577 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
578 Byte matchIpProto = flowObj.getMatchIpProto();
579 if (matchIpProto != null)
580 match.enableIpProto(matchIpProto);
581 Byte matchIpToS = flowObj.getMatchIpToS();
582 if (matchIpToS != null)
583 match.enableIpToS(matchIpToS);
584 Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
585 if (matchSrcTcpUdpPort != null)
586 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
587 Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
588 if (matchDstTcpUdpPort != null)
589 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
590
591 flowPath.setFlowEntryMatch(match);
592 }
593 //
594 // Extract the actions for the first Flow Entry
595 //
596 {
597 String actionsStr = flowObj.getActions();
598 if (actionsStr != null) {
599 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
600 flowPath.setFlowEntryActions(flowEntryActions);
601 }
602 }
603
604 //
605 // Extract all Flow Entries
606 //
607 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
608 for (IFlowEntry flowEntryObj : flowEntries) {
609 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
610 if (flowEntry == null)
611 continue;
612 flowPath.dataPath().flowEntries().add(flowEntry);
613 }
614
615 return flowPath;
616 }
617
618 /**
619 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
620 *
621 * @param flowEntryObj the object to extract the Flow Entry State from.
622 * @return the extracted Flow Entry State.
623 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700624 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700625 String flowEntryIdStr = flowEntryObj.getFlowEntryId();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800626 Integer idleTimeout = flowEntryObj.getIdleTimeout();
627 Integer hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700628 String switchDpidStr = flowEntryObj.getSwitchDpid();
629 String userState = flowEntryObj.getUserState();
630 String switchState = flowEntryObj.getSwitchState();
631
632 if ((flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800633 (idleTimeout == null) ||
634 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700635 (switchDpidStr == null) ||
636 (userState == null) ||
637 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -0700638 // TODO: A work-around, because of some bogus database objects
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700639 return null;
640 }
641
642 FlowEntry flowEntry = new FlowEntry();
643 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
644 flowEntry.setDpid(new Dpid(switchDpidStr));
645
646 //
647 // Extract the match conditions
648 //
649 FlowEntryMatch match = new FlowEntryMatch();
650 Short matchInPort = flowEntryObj.getMatchInPort();
651 if (matchInPort != null)
652 match.enableInPort(new Port(matchInPort));
653 String matchSrcMac = flowEntryObj.getMatchSrcMac();
654 if (matchSrcMac != null)
655 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
656 String matchDstMac = flowEntryObj.getMatchDstMac();
657 if (matchDstMac != null)
658 match.enableDstMac(MACAddress.valueOf(matchDstMac));
659 Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
660 if (matchEthernetFrameType != null)
661 match.enableEthernetFrameType(matchEthernetFrameType);
662 Short matchVlanId = flowEntryObj.getMatchVlanId();
663 if (matchVlanId != null)
664 match.enableVlanId(matchVlanId);
665 Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
666 if (matchVlanPriority != null)
667 match.enableVlanPriority(matchVlanPriority);
668 String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
669 if (matchSrcIPv4Net != null)
670 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
671 String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
672 if (matchDstIPv4Net != null)
673 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
674 Byte matchIpProto = flowEntryObj.getMatchIpProto();
675 if (matchIpProto != null)
676 match.enableIpProto(matchIpProto);
677 Byte matchIpToS = flowEntryObj.getMatchIpToS();
678 if (matchIpToS != null)
679 match.enableIpToS(matchIpToS);
680 Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
681 if (matchSrcTcpUdpPort != null)
682 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
683 Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
684 if (matchDstTcpUdpPort != null)
685 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
686 flowEntry.setFlowEntryMatch(match);
687
688 //
689 // Extract the actions
690 //
691 FlowEntryActions actions = new FlowEntryActions();
692 String actionsStr = flowEntryObj.getActions();
693 if (actionsStr != null)
694 actions = new FlowEntryActions(actionsStr);
695 flowEntry.setFlowEntryActions(actions);
696 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
697 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
698 //
699 // TODO: Take care of FlowEntryErrorState.
700 //
701 return flowEntry;
702 }
703}