blob: 835734fad29a4627675adadfdfac60de5de3c4eb [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 Radoslavovf3f23bb2014-01-10 13:02:33 -08006import java.util.Collection;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07007import java.util.LinkedList;
8import java.util.List;
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -08009import java.util.Map;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070010
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -080011import net.floodlightcontroller.core.IOFSwitch;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070012import net.floodlightcontroller.util.MACAddress;
13
14import net.onrc.onos.graph.GraphDBOperation;
15
16import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
17import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
18import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
19import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
20import net.onrc.onos.ofcontroller.util.*;
21
22import org.slf4j.Logger;
23import org.slf4j.LoggerFactory;
24
25/**
26 * Class for performing Flow-related operations on the Database.
27 */
Pavlin Radoslavov6bfaea62013-12-03 14:55:57 -080028public class FlowDatabaseOperation {
Pavlin Radoslavov909da3c2014-01-09 04:04:33 -080029 static private boolean enableOnrc2014MeasurementsFlows = true;
30
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070031 private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
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 */
Pavlin Radoslavov051abb42013-12-05 17:24:50 -080040 static boolean addFlow(GraphDBOperation dbHandler, FlowPath flowPath) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070041 IFlowPath flowObj = null;
42 boolean found = false;
43 try {
44 if ((flowObj = dbHandler.searchFlowPath(flowPath.flowId())) != null) {
45 found = true;
46 } else {
47 flowObj = dbHandler.newFlowPath();
48 }
49 } catch (Exception e) {
50 dbHandler.rollback();
51
52 StringWriter sw = new StringWriter();
53 e.printStackTrace(new PrintWriter(sw));
54 String stacktrace = sw.toString();
55
56 log.error(":addFlow FlowId:{} failed: {}",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080057 flowPath.flowId(),
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070058 stacktrace);
59 return false;
60 }
61 if (flowObj == null) {
62 log.error(":addFlow FlowId:{} failed: Flow object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -080063 flowPath.flowId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070064 dbHandler.rollback();
65 return false;
66 }
67
68 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -080069 // Remove the old Flow Entries
70 //
71 if (found) {
72 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
73 LinkedList<IFlowEntry> deleteFlowEntries =
74 new LinkedList<IFlowEntry>();
75 for (IFlowEntry flowEntryObj : flowEntries)
76 deleteFlowEntries.add(flowEntryObj);
77 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
78 flowObj.removeFlowEntry(flowEntryObj);
79 dbHandler.removeFlowEntry(flowEntryObj);
80 }
81 }
82
83 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070084 // Set the Flow key:
85 // - flowId
86 //
87 flowObj.setFlowId(flowPath.flowId().toString());
88 flowObj.setType("flow");
89
90 //
91 // Set the Flow attributes:
92 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -070093 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -070094 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070095 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -080096 // - flowPath.idleTimeout()
97 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070098 // - flowPath.dataPath().srcPort()
99 // - flowPath.dataPath().dstPort()
100 // - flowPath.matchSrcMac()
101 // - flowPath.matchDstMac()
102 // - flowPath.matchEthernetFrameType()
103 // - flowPath.matchVlanId()
104 // - flowPath.matchVlanPriority()
105 // - flowPath.matchSrcIPv4Net()
106 // - flowPath.matchDstIPv4Net()
107 // - flowPath.matchIpProto()
108 // - flowPath.matchIpToS()
109 // - flowPath.matchSrcTcpUdpPort()
110 // - flowPath.matchDstTcpUdpPort()
111 // - flowPath.flowEntryActions()
112 //
113 flowObj.setInstallerId(flowPath.installerId().toString());
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700114 flowObj.setFlowPathType(flowPath.flowPathType().toString());
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700115 flowObj.setFlowPathUserState(flowPath.flowPathUserState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700116 flowObj.setFlowPathFlags(flowPath.flowPathFlags().flags());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800117 flowObj.setIdleTimeout(flowPath.idleTimeout());
118 flowObj.setHardTimeout(flowPath.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700119 flowObj.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
120 flowObj.setSrcPort(flowPath.dataPath().srcPort().port().value());
121 flowObj.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
122 flowObj.setDstPort(flowPath.dataPath().dstPort().port().value());
123 if (flowPath.flowEntryMatch().matchSrcMac()) {
124 flowObj.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
125 }
126 if (flowPath.flowEntryMatch().matchDstMac()) {
127 flowObj.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
128 }
129 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
130 flowObj.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
131 }
132 if (flowPath.flowEntryMatch().matchVlanId()) {
133 flowObj.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
134 }
135 if (flowPath.flowEntryMatch().matchVlanPriority()) {
136 flowObj.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
137 }
138 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
139 flowObj.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
140 }
141 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
142 flowObj.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
143 }
144 if (flowPath.flowEntryMatch().matchIpProto()) {
145 flowObj.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
146 }
147 if (flowPath.flowEntryMatch().matchIpToS()) {
148 flowObj.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
149 }
150 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
151 flowObj.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
152 }
153 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
154 flowObj.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
155 }
156 if (! flowPath.flowEntryActions().actions().isEmpty()) {
157 flowObj.setActions(flowPath.flowEntryActions().toString());
158 }
Pavlin Radoslavovbcc86ef2013-10-26 12:06:25 -0700159 flowObj.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700160
161 if (found)
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700162 flowObj.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700163 else
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700164 flowObj.setFlowPathUserState("FP_USER_ADD");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700165
166 // Flow edges:
167 // HeadFE
168
169
170 //
171 // Flow Entries:
172 // flowPath.dataPath().flowEntries()
173 //
174 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavovbd077102014-01-10 13:46:48 -0800175 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE) {
176 continue; // Skip: all Flow Entries were deleted earlier
Pavlin Radoslavov909da3c2014-01-09 04:04:33 -0800177 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800178
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800179 if (addFlowEntry(dbHandler, flowObj, flowEntry) == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700180 dbHandler.rollback();
181 return false;
182 }
183 }
184 dbHandler.commit();
185
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700186 return true;
187 }
188
189 /**
190 * Add a flow entry to the Network MAP.
191 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700192 * @param dbHandler the Graph Database handler to use.
193 * @param flowObj the corresponding Flow Path object for the Flow Entry.
194 * @param flowEntry the Flow Entry to install.
195 * @return the added Flow Entry object on success, otherwise null.
196 */
Pavlin Radoslavov67bf7622013-12-04 12:28:23 -0800197 static IFlowEntry addFlowEntry(GraphDBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700198 IFlowPath flowObj,
199 FlowEntry flowEntry) {
200 // Flow edges
201 // HeadFE (TODO)
202
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700203 IFlowEntry flowEntryObj = null;
204 boolean found = false;
205 try {
206 if ((flowEntryObj =
207 dbHandler.searchFlowEntry(flowEntry.flowEntryId())) != null) {
208 found = true;
209 } else {
210 flowEntryObj = dbHandler.newFlowEntry();
211 }
212 } catch (Exception e) {
213 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800214 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700215 return null;
216 }
217 if (flowEntryObj == null) {
218 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800219 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700220 return null;
221 }
222
223 //
224 // Set the Flow Entry key:
225 // - flowEntry.flowEntryId()
226 //
227 flowEntryObj.setFlowEntryId(flowEntry.flowEntryId().toString());
228 flowEntryObj.setType("flow_entry");
229
230 //
231 // Set the Flow Entry Edges and attributes:
232 // - Switch edge
233 // - InPort edge
234 // - OutPort edge
235 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800236 // - flowEntry.idleTimeout()
237 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700238 // - flowEntry.dpid()
239 // - flowEntry.flowEntryUserState()
240 // - flowEntry.flowEntrySwitchState()
241 // - flowEntry.flowEntryErrorState()
242 // - flowEntry.matchInPort()
243 // - flowEntry.matchSrcMac()
244 // - flowEntry.matchDstMac()
245 // - flowEntry.matchEthernetFrameType()
246 // - flowEntry.matchVlanId()
247 // - flowEntry.matchVlanPriority()
248 // - flowEntry.matchSrcIPv4Net()
249 // - flowEntry.matchDstIPv4Net()
250 // - flowEntry.matchIpProto()
251 // - flowEntry.matchIpToS()
252 // - flowEntry.matchSrcTcpUdpPort()
253 // - flowEntry.matchDstTcpUdpPort()
254 // - flowEntry.actionOutputPort()
255 // - flowEntry.actions()
256 //
257 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800258 flowEntryObj.setIdleTimeout(flowEntry.idleTimeout());
259 flowEntryObj.setHardTimeout(flowEntry.hardTimeout());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700260 flowEntryObj.setSwitchDpid(flowEntry.dpid().toString());
261 flowEntryObj.setSwitch(sw);
262 if (flowEntry.flowEntryMatch().matchInPort()) {
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800263 IPortObject inport =
264 dbHandler.searchPort(flowEntry.dpid().toString(),
265 flowEntry.flowEntryMatch().inPort().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700266 flowEntryObj.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800267 flowEntryObj.setInPort(inport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700268 }
269 if (flowEntry.flowEntryMatch().matchSrcMac()) {
270 flowEntryObj.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
271 }
272 if (flowEntry.flowEntryMatch().matchDstMac()) {
273 flowEntryObj.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
274 }
275 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
276 flowEntryObj.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
277 }
278 if (flowEntry.flowEntryMatch().matchVlanId()) {
279 flowEntryObj.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
280 }
281 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
282 flowEntryObj.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
283 }
284 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
285 flowEntryObj.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
286 }
287 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
288 flowEntryObj.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
289 }
290 if (flowEntry.flowEntryMatch().matchIpProto()) {
291 flowEntryObj.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
292 }
293 if (flowEntry.flowEntryMatch().matchIpToS()) {
294 flowEntryObj.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
295 }
296 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
297 flowEntryObj.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
298 }
299 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
300 flowEntryObj.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
301 }
302
303 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
304 if (fa.actionOutput() != null) {
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800305 IPortObject outport =
306 dbHandler.searchPort(flowEntry.dpid().toString(),
307 fa.actionOutput().port().value());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700308 flowEntryObj.setActionOutputPort(fa.actionOutput().port().value());
Jonathan Hart5b3ad192013-12-06 17:34:46 -0800309 flowEntryObj.setOutPort(outport);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700310 }
311 }
312 if (! flowEntry.flowEntryActions().isEmpty()) {
313 flowEntryObj.setActions(flowEntry.flowEntryActions().toString());
314 }
315
316 // TODO: Hacks with hard-coded state names!
Pavlin Radoslavov9fde9b22014-01-09 14:03:52 -0800317 if (enableOnrc2014MeasurementsFlows) {
318 flowEntryObj.setUserState(flowEntry.flowEntryUserState().toString());
319 } else {
320 if (found)
321 flowEntryObj.setUserState("FE_USER_MODIFY");
322 else
323 flowEntryObj.setUserState("FE_USER_ADD");
324 }
Pavlin Radoslavovebc8b192013-10-29 15:35:35 -0700325 flowEntryObj.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700326 //
327 // TODO: Take care of the FlowEntryErrorState.
328 //
329
330 // Flow Entries edges:
331 // Flow
332 // NextFE (TODO)
333 if (! found) {
334 flowObj.addFlowEntry(flowEntryObj);
335 flowEntryObj.setFlow(flowObj);
336 }
337
338 return flowEntryObj;
339 }
340
341 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700342 * Delete a flow entry from the Network MAP.
343 *
344 * @param dbHandler the Graph Database handler to use.
345 * @param flowObj the corresponding Flow Path object for the Flow Entry.
346 * @param flowEntry the Flow Entry to delete.
347 * @return true on success, otherwise false.
348 */
349 static boolean deleteFlowEntry(GraphDBOperation dbHandler,
350 IFlowPath flowObj,
351 FlowEntry flowEntry) {
352 IFlowEntry flowEntryObj = null;
353 try {
354 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
355 } catch (Exception e) {
356 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800357 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700358 return false;
359 }
360 //
361 // TODO: Don't print an error for now, because multiple controller
362 // instances might be deleting the same flow entry.
363 //
364 /*
365 if (flowEntryObj == null) {
366 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800367 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700368 return false;
369 }
370 */
371 if (flowEntryObj == null)
372 return true;
373
374 flowObj.removeFlowEntry(flowEntryObj);
375 dbHandler.removeFlowEntry(flowEntryObj);
376 return true;
377 }
378
379 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700380 * Delete all previously added flows.
381 *
382 * @param dbHandler the Graph Database handler to use.
383 * @return true on success, otherwise false.
384 */
385 static boolean deleteAllFlows(GraphDBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700386 List<FlowId> allFlowIds = new LinkedList<FlowId>();
387
388 // Get all Flow IDs
389 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
390 for (IFlowPath flowPathObj : allFlowPaths) {
391 if (flowPathObj == null)
392 continue;
393 String flowIdStr = flowPathObj.getFlowId();
394 if (flowIdStr == null)
395 continue;
396 FlowId flowId = new FlowId(flowIdStr);
397 allFlowIds.add(flowId);
398 }
399
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800400 // Delete all flows one-by-one
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700401 for (FlowId flowId : allFlowIds) {
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800402 deleteFlow(dbHandler, flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700403 }
404
405 return true;
406 }
407
408 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800409 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700410 *
411 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800412 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700413 * @return true on success, otherwise false.
414 */
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800415 static boolean deleteFlow(GraphDBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700416 IFlowPath flowObj = null;
417 try {
418 flowObj = dbHandler.searchFlowPath(flowId);
419 } catch (Exception e) {
420 // TODO: handle exceptions
421 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800422 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700423 return false;
424 }
425 if (flowObj == null) {
426 dbHandler.commit();
427 return true; // OK: No such flow
428 }
429
430 //
431 // Remove all Flow Entries
432 //
433 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
434 for (IFlowEntry flowEntryObj : flowEntries) {
435 flowObj.removeFlowEntry(flowEntryObj);
436 dbHandler.removeFlowEntry(flowEntryObj);
437 }
438 // Remove the Flow itself
439 dbHandler.removeFlowPath(flowObj);
440 dbHandler.commit();
441
442 return true;
443 }
444
445 /**
446 * Get a previously added flow.
447 *
448 * @param dbHandler the Graph Database handler to use.
449 * @param flowId the Flow ID of the flow to get.
450 * @return the Flow Path if found, otherwise null.
451 */
452 static FlowPath getFlow(GraphDBOperation dbHandler, FlowId flowId) {
453 IFlowPath flowObj = null;
454 try {
455 flowObj = dbHandler.searchFlowPath(flowId);
456 } catch (Exception e) {
457 // TODO: handle exceptions
458 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800459 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700460 return null;
461 }
462 if (flowObj == null) {
463 dbHandler.commit();
464 return null; // Flow not found
465 }
466
467 //
468 // Extract the Flow state
469 //
470 FlowPath flowPath = extractFlowPath(flowObj);
471 dbHandler.commit();
472
473 return flowPath;
474 }
475
476 /**
Pavlin Radoslavov52119fa2014-01-09 13:37:52 -0800477 * Get a previously added flow entry.
478 *
479 * @param dbHandler the Graph Database handler to use.
480 * @param flowEntryId the Flow Entry ID of the flow entry to get.
481 * @return the Flow Entry if found, otherwise null.
482 */
483 static FlowEntry getFlowEntry(GraphDBOperation dbHandler,
484 FlowEntryId flowEntryId) {
485 IFlowEntry flowEntryObj = null;
486 try {
487 flowEntryObj = dbHandler.searchFlowEntry(flowEntryId);
488 } catch (Exception e) {
489 // TODO: handle exceptions
490 dbHandler.rollback();
491 log.error(":getFlowEntry FlowEntryId:{} failed", flowEntryId);
492 return null;
493 }
494 if (flowEntryObj == null) {
495 dbHandler.commit();
496 return null; // Flow not found
497 }
498
499 //
500 // Extract the Flow Entry state
501 //
502 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
503 dbHandler.commit();
504
505 return flowEntry;
506 }
507
508 /**
Pavlin Radoslavov8252fee2014-01-07 17:24:29 -0800509 * Get the source switch DPID of a previously added flow.
510 *
511 * @param dbHandler the Graph Database handler to use.
512 * @param flowId the Flow ID of the flow to get.
513 * @return the source switch DPID if found, otherwise null.
514 */
515 static Dpid getFlowSourceDpid(GraphDBOperation dbHandler, FlowId flowId) {
516 IFlowPath flowObj = null;
517 try {
518 flowObj = dbHandler.searchFlowPath(flowId);
519 } catch (Exception e) {
520 // TODO: handle exceptions
521 dbHandler.rollback();
522 log.error(":getFlowSourceDpid FlowId:{} failed", flowId);
523 return null;
524 }
525 if (flowObj == null) {
526 dbHandler.commit();
527 return null; // Flow not found
528 }
529
530 //
531 // Extract the Flow Source DPID
532 //
533 String srcSwitchStr = flowObj.getSrcSwitch();
534 if (srcSwitchStr == null) {
535 // TODO: A work-around, becauuse of some bogus database objects
536 dbHandler.commit();
537 return null;
538 }
539
540 Dpid dpid = new Dpid(srcSwitchStr);
541
542 dbHandler.commit();
543
544 return dpid;
545 }
546
547 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700548 * Get all installed flows by all installers.
549 *
550 * @param dbHandler the Graph Database handler to use.
551 * @return the Flow Paths if found, otherwise null.
552 */
553 static ArrayList<FlowPath> getAllFlows(GraphDBOperation dbHandler) {
554 Iterable<IFlowPath> flowPathsObj = null;
555 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
556
557 try {
558 flowPathsObj = dbHandler.getAllFlowPaths();
559 } catch (Exception e) {
560 // TODO: handle exceptions
561 dbHandler.rollback();
562 log.error(":getAllFlowPaths failed");
563 return flowPaths;
564 }
565 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
566 dbHandler.commit();
567 return flowPaths; // No Flows found
568 }
569
570 for (IFlowPath flowObj : flowPathsObj) {
571 //
572 // Extract the Flow state
573 //
574 FlowPath flowPath = extractFlowPath(flowObj);
575 if (flowPath != null)
576 flowPaths.add(flowPath);
577 }
578
579 dbHandler.commit();
580
581 return flowPaths;
582 }
583
584 /**
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -0800585 * Get all installed flows whose Source Switch is controlled by this
586 * instance.
587 *
588 * @param dbHandler the Graph Database handler to use.
589 * @param mySwitches the collection of the switches controlled by this
590 * instance.
591 * @return the Flow Paths if found, otherwise null.
592 */
593 static ArrayList<FlowPath> getAllMyFlows(GraphDBOperation dbHandler,
594 Map<Long, IOFSwitch> mySwitches) {
595 Iterable<IFlowPath> flowPathsObj = null;
596 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
597
598 try {
599 flowPathsObj = dbHandler.getAllFlowPaths();
600 } catch (Exception e) {
601 // TODO: handle exceptions
602 dbHandler.rollback();
603 log.error(":getAllMyFlowPaths failed");
604 return flowPaths;
605 }
606 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
607 dbHandler.commit();
608 return flowPaths; // No Flows found
609 }
610
611 for (IFlowPath flowObj : flowPathsObj) {
612 //
613 // Extract the Source Switch DPID and ignore if the switch
614 // is not controlled by this instance.
615 //
616 String srcSwitchStr = flowObj.getSrcSwitch();
617 if (srcSwitchStr == null) {
618 // TODO: A work-around, becauuse of some bogus database objects
619 continue;
620 }
621 Dpid dpid = new Dpid(srcSwitchStr);
622 if (mySwitches.get(dpid.value()) == null)
623 continue;
624
625 //
626 // Extract the Flow state
627 //
628 FlowPath flowPath = extractFlowPath(flowObj);
629 if (flowPath != null)
630 flowPaths.add(flowPath);
631 }
632
633 dbHandler.commit();
634
635 return flowPaths;
636 }
637
638 /**
Pavlin Radoslavovf3f23bb2014-01-10 13:02:33 -0800639 * Get a subset of installed flows.
640 *
641 * @param dbHandler the Graph Database handler to use.
642 * @param flowIds the collection of Flow IDs to get.
643 * @return the Flow Paths if found, otherwise null.
644 */
645 static ArrayList<FlowPath> getFlows(GraphDBOperation dbHandler,
646 Collection<FlowId> flowIds) {
647 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
648
649 // TODO: This implementation should use threads
650 for (FlowId flowId : flowIds) {
651 FlowPath flowPath = getFlow(dbHandler, flowId);
652 if (flowPath != null)
653 flowPaths.add(flowPath);
654 }
655 // dbHandler.commit();
656
657 return flowPaths;
658 }
659
660 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700661 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
662 *
663 * @param flowObj the object to extract the Flow Path State from.
664 * @return the extracted Flow Path State.
665 */
Brian O'Connor2c38efe2014-01-10 15:41:57 -0800666 static FlowPath extractFlowPath(IFlowPath flowObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700667 //
668 // Extract the Flow state
669 //
670 String flowIdStr = flowObj.getFlowId();
671 String installerIdStr = flowObj.getInstallerId();
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700672 String flowPathType = flowObj.getFlowPathType();
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700673 String flowPathUserState = flowObj.getFlowPathUserState();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700674 Long flowPathFlags = flowObj.getFlowPathFlags();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800675 Integer idleTimeout = flowObj.getIdleTimeout();
676 Integer hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700677 String srcSwitchStr = flowObj.getSrcSwitch();
678 Short srcPortShort = flowObj.getSrcPort();
679 String dstSwitchStr = flowObj.getDstSwitch();
680 Short dstPortShort = flowObj.getDstPort();
681
682 if ((flowIdStr == null) ||
683 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700684 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700685 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700686 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800687 (idleTimeout == null) ||
688 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700689 (srcSwitchStr == null) ||
690 (srcPortShort == null) ||
691 (dstSwitchStr == null) ||
692 (dstPortShort == null)) {
693 // TODO: A work-around, becauuse of some bogus database objects
694 return null;
695 }
696
697 FlowPath flowPath = new FlowPath();
698 flowPath.setFlowId(new FlowId(flowIdStr));
699 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700700 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700701 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700702 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800703 flowPath.setIdleTimeout(idleTimeout);
704 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700705 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
706 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
707 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
708 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
709 //
710 // Extract the match conditions common for all Flow Entries
711 //
712 {
713 FlowEntryMatch match = new FlowEntryMatch();
714 String matchSrcMac = flowObj.getMatchSrcMac();
715 if (matchSrcMac != null)
716 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
717 String matchDstMac = flowObj.getMatchDstMac();
718 if (matchDstMac != null)
719 match.enableDstMac(MACAddress.valueOf(matchDstMac));
720 Short matchEthernetFrameType = flowObj.getMatchEthernetFrameType();
721 if (matchEthernetFrameType != null)
722 match.enableEthernetFrameType(matchEthernetFrameType);
723 Short matchVlanId = flowObj.getMatchVlanId();
724 if (matchVlanId != null)
725 match.enableVlanId(matchVlanId);
726 Byte matchVlanPriority = flowObj.getMatchVlanPriority();
727 if (matchVlanPriority != null)
728 match.enableVlanPriority(matchVlanPriority);
729 String matchSrcIPv4Net = flowObj.getMatchSrcIPv4Net();
730 if (matchSrcIPv4Net != null)
731 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
732 String matchDstIPv4Net = flowObj.getMatchDstIPv4Net();
733 if (matchDstIPv4Net != null)
734 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
735 Byte matchIpProto = flowObj.getMatchIpProto();
736 if (matchIpProto != null)
737 match.enableIpProto(matchIpProto);
738 Byte matchIpToS = flowObj.getMatchIpToS();
739 if (matchIpToS != null)
740 match.enableIpToS(matchIpToS);
741 Short matchSrcTcpUdpPort = flowObj.getMatchSrcTcpUdpPort();
742 if (matchSrcTcpUdpPort != null)
743 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
744 Short matchDstTcpUdpPort = flowObj.getMatchDstTcpUdpPort();
745 if (matchDstTcpUdpPort != null)
746 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
747
748 flowPath.setFlowEntryMatch(match);
749 }
750 //
751 // Extract the actions for the first Flow Entry
752 //
753 {
754 String actionsStr = flowObj.getActions();
755 if (actionsStr != null) {
756 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
757 flowPath.setFlowEntryActions(flowEntryActions);
758 }
759 }
760
761 //
762 // Extract all Flow Entries
763 //
764 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
765 for (IFlowEntry flowEntryObj : flowEntries) {
766 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
767 if (flowEntry == null)
768 continue;
769 flowPath.dataPath().flowEntries().add(flowEntry);
770 }
771
772 return flowPath;
773 }
774
775 /**
776 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
777 *
778 * @param flowEntryObj the object to extract the Flow Entry State from.
779 * @return the extracted Flow Entry State.
780 */
Brian O'Connora8e49802013-10-30 20:49:59 -0700781 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800782 IFlowPath flowObj = flowEntryObj.getFlow();
783 if (flowObj == null)
784 return null;
785
786 String flowIdStr = flowObj.getFlowId();
787 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700788 String flowEntryIdStr = flowEntryObj.getFlowEntryId();
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800789 Integer idleTimeout = flowEntryObj.getIdleTimeout();
790 Integer hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700791 String switchDpidStr = flowEntryObj.getSwitchDpid();
792 String userState = flowEntryObj.getUserState();
793 String switchState = flowEntryObj.getSwitchState();
794
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800795 if ((flowIdStr == null) ||
796 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800797 (idleTimeout == null) ||
798 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700799 (switchDpidStr == null) ||
800 (userState == null) ||
801 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -0700802 // TODO: A work-around, because of some bogus database objects
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700803 return null;
804 }
805
806 FlowEntry flowEntry = new FlowEntry();
807 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -0800808 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700809 flowEntry.setDpid(new Dpid(switchDpidStr));
Pavlin Radoslavovce93a032013-12-13 11:03:02 -0800810 flowEntry.setIdleTimeout(idleTimeout);
811 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700812
813 //
814 // Extract the match conditions
815 //
816 FlowEntryMatch match = new FlowEntryMatch();
817 Short matchInPort = flowEntryObj.getMatchInPort();
818 if (matchInPort != null)
819 match.enableInPort(new Port(matchInPort));
820 String matchSrcMac = flowEntryObj.getMatchSrcMac();
821 if (matchSrcMac != null)
822 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
823 String matchDstMac = flowEntryObj.getMatchDstMac();
824 if (matchDstMac != null)
825 match.enableDstMac(MACAddress.valueOf(matchDstMac));
826 Short matchEthernetFrameType = flowEntryObj.getMatchEthernetFrameType();
827 if (matchEthernetFrameType != null)
828 match.enableEthernetFrameType(matchEthernetFrameType);
829 Short matchVlanId = flowEntryObj.getMatchVlanId();
830 if (matchVlanId != null)
831 match.enableVlanId(matchVlanId);
832 Byte matchVlanPriority = flowEntryObj.getMatchVlanPriority();
833 if (matchVlanPriority != null)
834 match.enableVlanPriority(matchVlanPriority);
835 String matchSrcIPv4Net = flowEntryObj.getMatchSrcIPv4Net();
836 if (matchSrcIPv4Net != null)
837 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
838 String matchDstIPv4Net = flowEntryObj.getMatchDstIPv4Net();
839 if (matchDstIPv4Net != null)
840 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
841 Byte matchIpProto = flowEntryObj.getMatchIpProto();
842 if (matchIpProto != null)
843 match.enableIpProto(matchIpProto);
844 Byte matchIpToS = flowEntryObj.getMatchIpToS();
845 if (matchIpToS != null)
846 match.enableIpToS(matchIpToS);
847 Short matchSrcTcpUdpPort = flowEntryObj.getMatchSrcTcpUdpPort();
848 if (matchSrcTcpUdpPort != null)
849 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
850 Short matchDstTcpUdpPort = flowEntryObj.getMatchDstTcpUdpPort();
851 if (matchDstTcpUdpPort != null)
852 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
853 flowEntry.setFlowEntryMatch(match);
854
855 //
856 // Extract the actions
857 //
858 FlowEntryActions actions = new FlowEntryActions();
859 String actionsStr = flowEntryObj.getActions();
860 if (actionsStr != null)
861 actions = new FlowEntryActions(actionsStr);
862 flowEntry.setFlowEntryActions(actions);
863 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
864 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
865 //
866 // TODO: Take care of FlowEntryErrorState.
867 //
868 return flowEntry;
869 }
870}