blob: d4a563bb621939724bfe8bd9ab8209705956ff9d [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 Radoslavov16b761d2014-01-08 09:47:14 -08008import java.util.Map;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07009
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -080010import net.floodlightcontroller.core.IOFSwitch;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070011import net.floodlightcontroller.util.MACAddress;
12
13import net.onrc.onos.graph.GraphDBOperation;
14
15import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
16import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
17import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
18import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
19import net.onrc.onos.ofcontroller.util.*;
20
21import org.slf4j.Logger;
22import org.slf4j.LoggerFactory;
23
24/**
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);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070029
30 /**
31 * Add a flow.
32 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070033 * @param dbHandler the Graph Database handler to use.
34 * @param flowPath the Flow Path to install.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070035 * @return true on success, otherwise false.
36 */
Pavlin Radoslavov051abb42013-12-05 17:24:50 -080037 static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070038 IFlowPath flowObj = null;
39 boolean found = false;
40 try {
41 if ((flowObj = dbHandler.searchFlowPath(flowPath.flowId())) != null) {
42 found = true;
43 } else {
44 flowObj = dbHandler.newFlowPath();
45 }
46 } catch (Exception e) {
47 dbHandler.rollback();
48
49 StringWriter sw = new StringWriter();
50 e.printStackTrace(new PrintWriter(sw));
51 String stacktrace = sw.toString();
52
53 log.error(":addFlow FlowId:{} failed: {}",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080054 flowPath.flowId(),
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070055 stacktrace);
56 return false;
57 }
58 if (flowObj == null) {
59 log.error(":addFlow FlowId:{} failed: Flow object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080060 flowPath.flowId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070061 dbHandler.rollback();
62 return false;
63 }
64
65 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080066 // Remove the old Flow Entries
67 //
68 if (found) {
69 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
70 LinkedList<IFlowEntry> deleteFlowEntries =
71 new LinkedList<IFlowEntry>();
72 for (IFlowEntry flowEntryObj : flowEntries)
73 deleteFlowEntries.add(flowEntryObj);
74 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
75 flowObj.removeFlowEntry(flowEntryObj);
76 dbHandler.removeFlowEntry(flowEntryObj);
77 }
78 }
79
80 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070081 // Set the Flow key:
82 // - flowId
83 //
84 flowObj.setFlowId(flowPath.flowId().toString());
85 flowObj.setType("flow");
86
87 //
88 // Set the Flow attributes:
89 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -070090 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -070091 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070092 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -080093 // - flowPath.idleTimeout()
94 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070095 // - flowPath.dataPath().srcPort()
96 // - flowPath.dataPath().dstPort()
97 // - flowPath.matchSrcMac()
98 // - flowPath.matchDstMac()
99 // - flowPath.matchEthernetFrameType()
100 // - flowPath.matchVlanId()
101 // - flowPath.matchVlanPriority()
102 // - flowPath.matchSrcIPv4Net()
103 // - flowPath.matchDstIPv4Net()
104 // - flowPath.matchIpProto()
105 // - flowPath.matchIpToS()
106 // - flowPath.matchSrcTcpUdpPort()
107 // - flowPath.matchDstTcpUdpPort()
108 // - flowPath.flowEntryActions()
109 //
110 flowObj.setInstallerId(flowPath.installerId().toString());
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700111 flowObj.setFlowPathType(flowPath.flowPathType().toString());
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700112 flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700113 flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800114 flowObj.setIdleTimeout(flowPath.idleTimeout());
115 flowObj.setHardTimeout(flowPath.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700116 flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
117 flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
118 flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
119 flowObj.setDstPort(flowPath.dataPath().dstPort().port().value());
120 if (flowPath.flowEntryMatch().matchSrcMac()) {
121 flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
122 }
123 if (flowPath.flowEntryMatch().matchDstMac()) {
124 flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
125 }
126 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
127 flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
128 }
129 if (flowPath.flowEntryMatch().matchVlanId()) {
130 flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
131 }
132 if (flowPath.flowEntryMatch().matchVlanPriority()) {
133 flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
134 }
135 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
136 flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
137 }
138 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
139 flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
140 }
141 if (flowPath.flowEntryMatch().matchIpProto()) {
142 flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
143 }
144 if (flowPath.flowEntryMatch().matchIpToS()) {
145 flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
146 }
147 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
148 flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
149 }
150 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
151 flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
152 }
153 if (! flowPath.flowEntryActions().actions().isEmpty()) {
154 flowObj.setActions(flowPath.flowEntryActions().toString());
155 }
Pavlin Radoslavovbcc86ef2013-10-26 12:06:25 -0700156 flowObj.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700157
158 if (found)
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700159 flowObj.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700160 else
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700161 flowObj.setFlowPathUserState("FP_USER_ADD");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700162
163 // Flow edges:
164 // HeadFE
165
166
167 //
168 // Flow Entries:
169 // flowPath.dataPath().flowEntries()
170 //
171 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800172 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
173 continue; // Skip: all Flow Entries were deleted earlier
174
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800175 if (addFlowEntry(dbHandler, flowObj, flowEntry) == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700176 dbHandler.rollback();
177 return false;
178 }
179 }
180 dbHandler.commit();
181
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700182 return true;
183 }
184
185 /**
186 * Add a flow entry to the Network MAP.
187 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700188 * @param dbHandler the Graph Database handler to use.
189 * @param flowObj the corresponding Flow Path object for the Flow Entry.
190 * @param flowEntry the Flow Entry to install.
191 * @return the added Flow Entry object on success, otherwise null.
192 */
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800193 static IFlowEntry addFlowEntry(GraphDBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700194 IFlowPath flowObj,
195 FlowEntry flowEntry) {
196 // Flow edges
197 // HeadFE (TODO)
198
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700199 IFlowEntry flowEntryObj = null;
200 boolean found = false;
201 try {
202 if ((flowEntryObj =
203 dbHandler.searchFlowEntry(flowEntry.flowEntryId())) != null) {
204 found = true;
205 } else {
206 flowEntryObj = dbHandler.newFlowEntry();
207 }
208 } catch (Exception e) {
209 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800210 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700211 return null;
212 }
213 if (flowEntryObj == null) {
214 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800215 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700216 return null;
217 }
218
219 //
220 // Set the Flow Entry key:
221 // - flowEntry.flowEntryId()
222 //
223 flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
224 flowEntryObj.setType("flow_entry");
225
226 //
227 // Set the Flow Entry Edges and attributes:
228 // - Switch edge
229 // - InPort edge
230 // - OutPort edge
231 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800232 // - flowEntry.idleTimeout()
233 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700234 // - flowEntry.dpid()
235 // - flowEntry.flowEntryUserState()
236 // - flowEntry.flowEntrySwitchState()
237 // - flowEntry.flowEntryErrorState()
238 // - flowEntry.matchInPort()
239 // - flowEntry.matchSrcMac()
240 // - flowEntry.matchDstMac()
241 // - flowEntry.matchEthernetFrameType()
242 // - flowEntry.matchVlanId()
243 // - flowEntry.matchVlanPriority()
244 // - flowEntry.matchSrcIPv4Net()
245 // - flowEntry.matchDstIPv4Net()
246 // - flowEntry.matchIpProto()
247 // - flowEntry.matchIpToS()
248 // - flowEntry.matchSrcTcpUdpPort()
249 // - flowEntry.matchDstTcpUdpPort()
250 // - flowEntry.actionOutputPort()
251 // - flowEntry.actions()
252 //
253 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800254 flowEntryObj.setIdleTimeout(flowEntry.idleTimeout());
255 flowEntryObj.setHardTimeout(flowEntry.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700256 flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
257 flowEntryObj.setSwitch(sw);
258 if (flowEntry.flowEntryMatch().matchInPort()) {
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800259 IPortObject inport =
260 dbHandler.searchPort(flowEntry.dpid().toString(),
261 flowEntry.flowEntryMatch().inPort().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700262 flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800263 flowEntryObj.setInPort(inport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700264 }
265 if (flowEntry.flowEntryMatch().matchSrcMac()) {
266 flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
267 }
268 if (flowEntry.flowEntryMatch().matchDstMac()) {
269 flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
270 }
271 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
272 flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
273 }
274 if (flowEntry.flowEntryMatch().matchVlanId()) {
275 flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
276 }
277 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
278 flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
279 }
280 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
281 flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
282 }
283 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
284 flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
285 }
286 if (flowEntry.flowEntryMatch().matchIpProto()) {
287 flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
288 }
289 if (flowEntry.flowEntryMatch().matchIpToS()) {
290 flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
291 }
292 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
293 flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
294 }
295 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
296 flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
297 }
298
299 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
300 if (fa.actionOutput() != null) {
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800301 IPortObject outport =
302 dbHandler.searchPort(flowEntry.dpid().toString(),
303 fa.actionOutput().port().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700304 flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800305 flowEntryObj.setOutPort(outport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700306 }
307 }
308 if (! flowEntry.flowEntryActions().isEmpty()) {
309 flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
310 }
311
312 // TODO: Hacks with hard-coded state names!
313 if (found)
314 flowEntryObj.setUserState("FE_USER_MODIFY");
315 else
316 flowEntryObj.setUserState("FE_USER_ADD");
Pavlin Radoslavovebc8b192013-10-29 15:35:35 -0700317 flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700318 //
319 // TODO: Take care of the FlowEntryErrorState.
320 //
321
322 // Flow Entries edges:
323 // Flow
324 // NextFE (TODO)
325 if (! found) {
326 flowObj.addFlowEntry(flowEntryObj);
327 flowEntryObj.setFlow(flowObj);
328 }
329
330 return flowEntryObj;
331 }
332
333 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700334 * Delete a flow entry from the Network MAP.
335 *
336 * @param dbHandler the Graph Database handler to use.
337 * @param flowObj the corresponding Flow Path object for the Flow Entry.
338 * @param flowEntry the Flow Entry to delete.
339 * @return true on success, otherwise false.
340 */
341 static boolean deleteFlowEntry(GraphDBOperation dbHandler,
342 IFlowPath flowObj,
343 FlowEntry flowEntry) {
344 IFlowEntry flowEntryObj = null;
345 try {
346 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
347 } catch (Exception e) {
348 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800349 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700350 return false;
351 }
352 //
353 // TODO: Don't print an error for now, because multiple controller
354 // instances might be deleting the same flow entry.
355 //
356 /*
357 if (flowEntryObj == null) {
358 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800359 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700360 return false;
361 }
362 */
363 if (flowEntryObj == null)
364 return true;
365
366 flowObj.removeFlowEntry(flowEntryObj);
367 dbHandler.removeFlowEntry(flowEntryObj);
368 return true;
369 }
370
371 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700372 * Delete all previously added flows.
373 *
374 * @param dbHandler the Graph Database handler to use.
375 * @return true on success, otherwise false.
376 */
377 static boolean deleteAllFlows(GraphDBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700378 List<FlowId> allFlowIds = new LinkedList<FlowId>();
379
380 // Get all Flow IDs
381 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
382 for (IFlowPath flowPathObj : allFlowPaths) {
383 if (flowPathObj == null)
384 continue;
385 String flowIdStr = flowPathObj.getFlowId();
386 if (flowIdStr == null)
387 continue;
388 FlowId flowId = new FlowId(flowIdStr);
389 allFlowIds.add(flowId);
390 }
391
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800392 // Delete all flows one-by-one
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700393 for (FlowId flowId : allFlowIds) {
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800394 deleteFlow(dbHandler, flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700395 }
396
397 return true;
398 }
399
400 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800401 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700402 *
403 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800404 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700405 * @return true on success, otherwise false.
406 */
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800407 static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700408 IFlowPath flowObj = null;
409 try {
410 flowObj = dbHandler.searchFlowPath(flowId);
411 } catch (Exception e) {
412 // TODO: handle exceptions
413 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800414 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700415 return false;
416 }
417 if (flowObj == null) {
418 dbHandler.commit();
419 return true; // OK: No such flow
420 }
421
422 //
423 // Remove all Flow Entries
424 //
425 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
426 for (IFlowEntry flowEntryObj : flowEntries) {
427 flowObj.removeFlowEntry(flowEntryObj);
428 dbHandler.removeFlowEntry(flowEntryObj);
429 }
430 // Remove the Flow itself
431 dbHandler.removeFlowPath(flowObj);
432 dbHandler.commit();
433
434 return true;
435 }
436
437 /**
438 * Get a previously added flow.
439 *
440 * @param dbHandler the Graph Database handler to use.
441 * @param flowId the Flow ID of the flow to get.
442 * @return the Flow Path if found, otherwise null.
443 */
444 static FlowPath getFlow(GraphDBOperation dbHandler, FlowId flowId) {
445 IFlowPath flowObj = null;
446 try {
447 flowObj = dbHandler.searchFlowPath(flowId);
448 } catch (Exception e) {
449 // TODO: handle exceptions
450 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800451 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700452 return null;
453 }
454 if (flowObj == null) {
455 dbHandler.commit();
456 return null; // Flow not found
457 }
458
459 //
460 // Extract the Flow state
461 //
462 FlowPath flowPath = extractFlowPath(flowObj);
463 dbHandler.commit();
464
465 return flowPath;
466 }
467
468 /**
Pavlin Radoslavov8252fee2014-01-07 17:24:29 -0800469 * Get the source switch DPID of a previously added flow.
470 *
471 * @param dbHandler the Graph Database handler to use.
472 * @param flowId the Flow ID of the flow to get.
473 * @return the source switch DPID if found, otherwise null.
474 */
475 static Dpid getFlowSourceDpid(GraphDBOperation dbHandler, FlowId flowId) {
476 IFlowPath flowObj = null;
477 try {
478 flowObj = dbHandler.searchFlowPath(flowId);
479 } catch (Exception e) {
480 // TODO: handle exceptions
481 dbHandler.rollback();
482 log.error(":getFlowSourceDpid FlowId:{} failed", flowId);
483 return null;
484 }
485 if (flowObj == null) {
486 dbHandler.commit();
487 return null; // Flow not found
488 }
489
490 //
491 // Extract the Flow Source DPID
492 //
493 String srcSwitchStr = flowObj.getSrcSwitch();
494 if (srcSwitchStr == null) {
495 // TODO: A work-around, becauuse of some bogus database objects
496 dbHandler.commit();
497 return null;
498 }
499
500 Dpid dpid = new Dpid(srcSwitchStr);
501
502 dbHandler.commit();
503
504 return dpid;
505 }
506
507 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700508 * Get all installed flows by all installers.
509 *
510 * @param dbHandler the Graph Database handler to use.
511 * @return the Flow Paths if found, otherwise null.
512 */
513 static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler) {
514 Iterable<IFlowPath> flowPathsObj = null;
515 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
516
517 try {
518 flowPathsObj = dbHandler.getAllFlowPaths();
519 } catch (Exception e) {
520 // TODO: handle exceptions
521 dbHandler.rollback();
522 log.error(":getAllFlowPaths failed");
523 return flowPaths;
524 }
525 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
526 dbHandler.commit();
527 return flowPaths; // No Flows found
528 }
529
530 for (IFlowPath flowObj : flowPathsObj) {
531 //
532 // Extract the Flow state
533 //
534 FlowPath flowPath = extractFlowPath(flowObj);
535 if (flowPath != null)
536 flowPaths.add(flowPath);
537 }
538
539 dbHandler.commit();
540
541 return flowPaths;
542 }
543
544 /**
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -0800545 * Get all installed flows whose Source Switch is controlled by this
546 * instance.
547 *
548 * @param dbHandler the Graph Database handler to use.
549 * @param mySwitches the collection of the switches controlled by this
550 * instance.
551 * @return the Flow Paths if found, otherwise null.
552 */
553 static ArrayList<FlowPath> getAllMyFlows(GraphDBOperation dbHandler,
554 Map<Long, IOFSwitch> mySwitches) {
555 Iterable<IFlowPath> flowPathsObj = null;
556 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
557
558 try {
559 flowPathsObj = dbHandler.getAllFlowPaths();
560 } catch (Exception e) {
561 // TODO: handle exceptions
562 dbHandler.rollback();
563 log.error(":getAllMyFlowPaths failed");
564 return flowPaths;
565 }
566 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
567 dbHandler.commit();
568 return flowPaths; // No Flows found
569 }
570
571 for (IFlowPath flowObj : flowPathsObj) {
572 //
573 // Extract the Source Switch DPID and ignore if the switch
574 // is not controlled by this instance.
575 //
576 String srcSwitchStr = flowObj.getSrcSwitch();
577 if (srcSwitchStr == null) {
578 // TODO: A work-around, becauuse of some bogus database objects
579 continue;
580 }
581 Dpid dpid = new Dpid(srcSwitchStr);
582 if (mySwitches.get(dpid.value()) == null)
583 continue;
584
585 //
586 // Extract the Flow state
587 //
588 FlowPath flowPath = extractFlowPath(flowObj);
589 if (flowPath != null)
590 flowPaths.add(flowPath);
591 }
592
593 dbHandler.commit();
594
595 return flowPaths;
596 }
597
598 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700599 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
600 *
601 * @param flowObj the object to extract the Flow Path State from.
602 * @return the extracted Flow Path State.
603 */
604 private static FlowPath extractFlowPath(IFlowPath flowObj) {
605 //
606 // Extract the Flow state
607 //
608 String flowIdStr = flowObj.getFlowId();
609 String installerIdStr = flowObj.getInstallerId();
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700610 String flowPathType = flowObj.getFlowPathType();
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700611 String flowPathUserState = flowObj.getFlowPathUserState();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700612 Long flowPathFlags = flowObj.getFlowPathFlags();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800613 Integer idleTimeout = flowObj.getIdleTimeout();
614 Integer hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700615 String srcSwitchStr = flowObj.getSrcSwitch();
616 Short srcPortShort = flowObj.getSrcPort();
617 String dstSwitchStr = flowObj.getDstSwitch();
618 Short dstPortShort = flowObj.getDstPort();
619
620 if ((flowIdStr == null) ||
621 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700622 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700623 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700624 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800625 (idleTimeout == null) ||
626 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700627 (srcSwitchStr == null) ||
628 (srcPortShort == null) ||
629 (dstSwitchStr == null) ||
630 (dstPortShort == null)) {
631 // TODO: A work-around, becauuse of some bogus database objects
632 return null;
633 }
634
635 FlowPath flowPath = new FlowPath();
636 flowPath.setFlowId(new FlowId(flowIdStr));
637 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700638 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700639 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700640 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800641 flowPath.setIdleTimeout(idleTimeout);
642 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700643 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
644 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
645 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
646 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
647 //
648 // Extract the match conditions common for all Flow Entries
649 //
650 {
651 FlowEntryMatch match = new FlowEntryMatch();
652 String matchSrcMac = flowObj.getMatchSrcMac();
653 if (matchSrcMac != null)
654 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
655 String matchDstMac = flowObj.getMatchDstMac();
656 if (matchDstMac != null)
657 match.enableDstMac(MACAddress.valueOf(matchDstMac));
658 Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
659 if (matchEthernetFrameType != null)
660 match.enableEthernetFrameType(matchEthernetFrameType);
661 Short matchVlanId = flowObj.getMatchVlanId();
662 if (matchVlanId != null)
663 match.enableVlanId(matchVlanId);
664 Byte matchVlanPriority = flowObj.getMatchVlanPriority();
665 if (matchVlanPriority != null)
666 match.enableVlanPriority(matchVlanPriority);
667 String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
668 if (matchSrcIPv4Net != null)
669 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
670 String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
671 if (matchDstIPv4Net != null)
672 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
673 Byte matchIpProto = flowObj.getMatchIpProto();
674 if (matchIpProto != null)
675 match.enableIpProto(matchIpProto);
676 Byte matchIpToS = flowObj.getMatchIpToS();
677 if (matchIpToS != null)
678 match.enableIpToS(matchIpToS);
679 Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
680 if (matchSrcTcpUdpPort != null)
681 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
682 Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
683 if (matchDstTcpUdpPort != null)
684 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
685
686 flowPath.setFlowEntryMatch(match);
687 }
688 //
689 // Extract the actions for the first Flow Entry
690 //
691 {
692 String actionsStr = flowObj.getActions();
693 if (actionsStr != null) {
694 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
695 flowPath.setFlowEntryActions(flowEntryActions);
696 }
697 }
698
699 //
700 // Extract all Flow Entries
701 //
702 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
703 for (IFlowEntry flowEntryObj : flowEntries) {
704 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
705 if (flowEntry == null)
706 continue;
707 flowPath.dataPath().flowEntries().add(flowEntry);
708 }
709
710 return flowPath;
711 }
712
713 /**
714 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
715 *
716 * @param flowEntryObj the object to extract the Flow Entry State from.
717 * @return the extracted Flow Entry State.
718 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700719 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800720 IFlowPath flowObj = flowEntryObj.getFlow();
721 if (flowObj == null)
722 return null;
723
724 String flowIdStr = flowObj.getFlowId();
725 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700726 String flowEntryIdStr = flowEntryObj.getFlowEntryId();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800727 Integer idleTimeout = flowEntryObj.getIdleTimeout();
728 Integer hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700729 String switchDpidStr = flowEntryObj.getSwitchDpid();
730 String userState = flowEntryObj.getUserState();
731 String switchState = flowEntryObj.getSwitchState();
732
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800733 if ((flowIdStr == null) ||
734 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800735 (idleTimeout == null) ||
736 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700737 (switchDpidStr == null) ||
738 (userState == null) ||
739 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -0700740 // TODO: A work-around, because of some bogus database objects
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700741 return null;
742 }
743
744 FlowEntry flowEntry = new FlowEntry();
745 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800746 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700747 flowEntry.setDpid(new Dpid(switchDpidStr));
Pavlin Radoslavovce93a032013-12-13 11:03:02 -0800748 flowEntry.setIdleTimeout(idleTimeout);
749 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700750
751 //
752 // Extract the match conditions
753 //
754 FlowEntryMatch match = new FlowEntryMatch();
755 Short matchInPort = flowEntryObj.getMatchInPort();
756 if (matchInPort != null)
757 match.enableInPort(new Port(matchInPort));
758 String matchSrcMac = flowEntryObj.getMatchSrcMac();
759 if (matchSrcMac != null)
760 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
761 String matchDstMac = flowEntryObj.getMatchDstMac();
762 if (matchDstMac != null)
763 match.enableDstMac(MACAddress.valueOf(matchDstMac));
764 Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
765 if (matchEthernetFrameType != null)
766 match.enableEthernetFrameType(matchEthernetFrameType);
767 Short matchVlanId = flowEntryObj.getMatchVlanId();
768 if (matchVlanId != null)
769 match.enableVlanId(matchVlanId);
770 Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
771 if (matchVlanPriority != null)
772 match.enableVlanPriority(matchVlanPriority);
773 String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
774 if (matchSrcIPv4Net != null)
775 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
776 String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
777 if (matchDstIPv4Net != null)
778 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
779 Byte matchIpProto = flowEntryObj.getMatchIpProto();
780 if (matchIpProto != null)
781 match.enableIpProto(matchIpProto);
782 Byte matchIpToS = flowEntryObj.getMatchIpToS();
783 if (matchIpToS != null)
784 match.enableIpToS(matchIpToS);
785 Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
786 if (matchSrcTcpUdpPort != null)
787 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
788 Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
789 if (matchDstTcpUdpPort != null)
790 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
791 flowEntry.setFlowEntryMatch(match);
792
793 //
794 // Extract the actions
795 //
796 FlowEntryActions actions = new FlowEntryActions();
797 String actionsStr = flowEntryObj.getActions();
798 if (actionsStr != null)
799 actions = new FlowEntryActions(actionsStr);
800 flowEntry.setFlowEntryActions(actions);
801 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
802 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
803 //
804 // TODO: Take care of FlowEntryErrorState.
805 //
806 return flowEntry;
807 }
808}