blob: 2793dd49b9be27b281da739e227387efeb5615f9 [file] [log] [blame]
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001package net.onrc.onos.ofcontroller.flowmanager;
2
Nick Karanatsios758df8d2014-01-14 22:16:32 -08003import com.tinkerpop.blueprints.Direction;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07004import java.io.PrintWriter;
5import java.io.StringWriter;
6import java.util.ArrayList;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07007import java.util.LinkedList;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08008import java.util.Map;
9
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070010import net.floodlightcontroller.util.MACAddress;
yoshitomob292c622013-11-23 14:35:58 -080011import net.onrc.onos.graph.DBOperation;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -080012import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070013import 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
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080022import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -080023import com.tinkerpop.blueprints.impls.ramcloud.RamCloudVertex;
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080024
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070025/**
26 * Class for performing Flow-related operations on the Database.
27 */
Pavlin Radoslavov6bfaea62013-12-03 14:55:57 -080028public class FlowDatabaseOperation {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070029 private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080030 private static final boolean measureONOSFlowTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlow", "0")) != 0;
31 private static final boolean measureONOSFlowEntryTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlowEntry", "0")) != 0;
Toshio Koidec71b7122014-01-13 15:16:53 -080032 private static final boolean useFastAddFlow = true;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070033
34 /**
35 * Add a flow.
36 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070037 * @param dbHandler the Graph Database handler to use.
38 * @param flowPath the Flow Path to install.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070039 * @return true on success, otherwise false.
40 */
Toshio Koidec71b7122014-01-13 15:16:53 -080041 static boolean addFlowFast(DBOperation dbHandler, FlowPath flowPath) {
42 IFlowPath flowPathObj = null;
43 FlowPathProperty flowProp = new FlowPathProperty();
Nick Karanatsios758df8d2014-01-14 22:16:32 -080044 FlowEntity flowPathEntity = new FlowEntity();
45 boolean flowPathUpdate = false;
Toshio Koidec71b7122014-01-13 15:16:53 -080046
47 flowPathObj = dbHandler.searchFlowPath(flowPath.flowId()); // toshi memo: getVertices("flow_id")
48 if (flowPathObj == null) {
49 try {
Nick Karanatsios758df8d2014-01-14 22:16:32 -080050 flowPathEntity.operationBegin(DBOperationType.ADD.toString());
Toshio Koidec71b7122014-01-13 15:16:53 -080051 flowPathObj = dbHandler.newFlowPath(); // toshi memo: addVertex(), setType("flow")
52 } catch (Exception e) {
53 flowPathObj = null;
54 StringWriter sw = new StringWriter();
55 e.printStackTrace(new PrintWriter(sw));
56 log.error(":addFlow FlowId:{} failed: {}", flowPath.flowId(), sw.toString());
57 }
Nick Karanatsios758df8d2014-01-14 22:16:32 -080058 flowPathEntity.setProperty("user_state", "FP_USER_ADD");
Toshio Koidec71b7122014-01-13 15:16:53 -080059 flowProp.setFlowPathUserState("FP_USER_ADD");
60 } else {
Nick Karanatsios758df8d2014-01-14 22:16:32 -080061 flowPathUpdate = true;
Toshio Koidec71b7122014-01-13 15:16:53 -080062 // Remove the old Flow Entries (this is special for RAMCloud)
63 for (IFlowEntry flowEntryObj : flowPathObj.getFlowEntries()) { // toshi memo: get.@Adjacency("flow", IN)
64 //flowObj.removeFlowEntry(flowEntryObj); // toshi memo: remove.@Adjacency("flow", IN)
Nick Karanatsios758df8d2014-01-14 22:16:32 -080065 flowPathEntity.operationBegin(DBOperationType.REMOVE.toString());
Toshio Koidec71b7122014-01-13 15:16:53 -080066 dbHandler.removeFlowEntry(flowEntryObj); // toshi memo: removeVertex()
Nick Karanatsios758df8d2014-01-14 22:16:32 -080067 flowPathEntity.operationEnd(DBOperationType.REMOVE.toString());
Toshio Koidec71b7122014-01-13 15:16:53 -080068 }
Nick Karanatsios758df8d2014-01-14 22:16:32 -080069 flowPathEntity.operationBegin(DBOperationType.UPDATE.toString());
70 flowPathEntity.setProperty("user_state", "FP_USER_ADD");
Toshio Koidec71b7122014-01-13 15:16:53 -080071 flowProp.setFlowPathUserState("FP_USER_MODIFY");
72 }
73 if (flowPathObj == null) {
74 log.error(":addFlow FlowId:{} failed: Flow object not created", flowPath.flowId());
75 dbHandler.rollback();
76
77 return false;
78 }
79
Nick Karanatsios758df8d2014-01-14 22:16:32 -080080 flowPathEntity.setProperty("flow_id", flowPath.flowId().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -080081 // Set the Flow key
82 flowProp.setFlowId(flowPath.flowId().toString());
83
84 // Set the Flow attributes
Nick Karanatsios758df8d2014-01-14 22:16:32 -080085
86 flowPathEntity.setProperty("installer_id", flowPath.installerId().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -080087 flowProp.setInstallerId(flowPath.installerId().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -080088
89 flowPathEntity.setProperty("flow_path_type", flowPath.flowPathType().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -080090 flowProp.setFlowPathType(flowPath.flowPathType().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -080091
92 flowPathEntity.setProperty("user_state", flowPath.flowPathUserState().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -080093 flowProp.setFlowPathUserState(flowPath.flowPathUserState().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -080094
95
96 flowPathEntity.setProperty("flow_path_flags", flowPath.flowPathFlags().flags());
Toshio Koidec71b7122014-01-13 15:16:53 -080097 flowProp.setFlowPathFlags(flowPath.flowPathFlags().flags());
Nick Karanatsios758df8d2014-01-14 22:16:32 -080098
99 flowPathEntity.setProperty("idle_timeout", flowPath.idleTimeout());
Toshio Koidec71b7122014-01-13 15:16:53 -0800100 flowProp.setIdleTimeout(flowPath.idleTimeout());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800101
102 flowPathEntity.setProperty("hard_timeout", flowPath.hardTimeout());
Toshio Koidec71b7122014-01-13 15:16:53 -0800103 flowProp.setHardTimeout(flowPath.hardTimeout());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800104
105 flowPathEntity.setProperty("src_switch", flowPath.dataPath().srcPort().dpid().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800106 flowProp.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800107
108 flowPathEntity.setProperty("src_port", flowPath.dataPath().srcPort().port().value());
Toshio Koidec71b7122014-01-13 15:16:53 -0800109 flowProp.setSrcPort(flowPath.dataPath().srcPort().port().value());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800110
111 flowPathEntity.setProperty("dst_switch", flowPath.dataPath().dstPort().dpid().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800112 flowProp.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800113
114 flowPathEntity.setProperty("dst_port", flowPath.dataPath().dstPort().port().value());
Toshio Koidec71b7122014-01-13 15:16:53 -0800115 flowProp.setDstPort(flowPath.dataPath().dstPort().port().value());
116
117 if (flowPath.flowEntryMatch().matchSrcMac()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800118 flowPathEntity.setProperty("matchSrcMac",flowPath.flowEntryMatch().srcMac().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800119 flowProp.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
120 }
121 if (flowPath.flowEntryMatch().matchDstMac()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800122 flowPathEntity.setProperty("matchDstMac", flowPath.flowEntryMatch().dstMac().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800123 flowProp.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
124 }
125 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800126 flowPathEntity.setProperty("matchEthernetFrameType", flowPath.flowEntryMatch().ethernetFrameType());
Toshio Koidec71b7122014-01-13 15:16:53 -0800127 flowProp.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
128 }
129 if (flowPath.flowEntryMatch().matchVlanId()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800130 flowPathEntity.setProperty("matchVlanId", flowPath.flowEntryMatch().vlanId());
Toshio Koidec71b7122014-01-13 15:16:53 -0800131 flowProp.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
132 }
133 if (flowPath.flowEntryMatch().matchVlanPriority()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800134 flowPathEntity.setProperty("matchVlanPriority", flowPath.flowEntryMatch().vlanPriority());
Toshio Koidec71b7122014-01-13 15:16:53 -0800135 flowProp.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
136 }
137 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800138 flowPathEntity.setProperty("matchSrcIPv4Net", flowPath.flowEntryMatch().srcIPv4Net().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800139 flowProp.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
140 }
141 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800142 flowPathEntity.setProperty("matchDstIPv4Net", flowPath.flowEntryMatch().dstIPv4Net().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800143 flowProp.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
144 }
145 if (flowPath.flowEntryMatch().matchIpProto()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800146 flowPathEntity.setProperty("matchIpProto", flowPath.flowEntryMatch().ipProto());
Toshio Koidec71b7122014-01-13 15:16:53 -0800147 flowProp.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
148 }
149 if (flowPath.flowEntryMatch().matchIpToS()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800150 flowPathEntity.setProperty("matchIpToS", flowPath.flowEntryMatch().ipToS());
Toshio Koidec71b7122014-01-13 15:16:53 -0800151 flowProp.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
152 }
153 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800154 flowPathEntity.setProperty("matchSrcTcpUdpPort", flowPath.flowEntryMatch().srcTcpUdpPort());
Toshio Koidec71b7122014-01-13 15:16:53 -0800155 flowProp.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
156 }
157 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800158 flowPathEntity.setProperty("matchDstTcpUdpPort", flowPath.flowEntryMatch().dstTcpUdpPort());
Toshio Koidec71b7122014-01-13 15:16:53 -0800159 flowProp.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
160 }
161 if (! flowPath.flowEntryActions().actions().isEmpty()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800162 flowPathEntity.setProperty("actions", flowPath.flowEntryActions().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800163 flowProp.setActions(flowPath.flowEntryActions().toString());
164 }
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800165 flowPathEntity.setProperty("data_path_summary", flowPath.dataPath().dataPathSummary());
Toshio Koidec71b7122014-01-13 15:16:53 -0800166 flowProp.setDataPathSummary(flowPath.dataPath().dataPathSummary());
167
168 flowProp.commitProperties(dbHandler, flowPathObj); // toshi memo: flowObj.setProperties()
169
170 //
171 // Flow Entries:
172 // flowPath.dataPath().flowEntries()
173 //
174 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
175 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
176 continue; // Skip: all Flow Entries were deleted earlier
177
178 IFlowEntry iFlowEntry = null;
179 FlowEntryProperty flowEntryProp = new FlowEntryProperty();
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800180 FlowEntity flowEntryEntity = new FlowEntity();
181 boolean updateFlowEntry = false;
Toshio Koidec71b7122014-01-13 15:16:53 -0800182
183 try {
184 iFlowEntry = dbHandler.searchFlowEntry(flowEntry.flowEntryId()); // toshi memo: getVertices()
185 if (iFlowEntry != null) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800186 updateFlowEntry = true;
187 flowEntryEntity.operationBegin(DBOperationType.UPDATE.toString());
188 flowEntryEntity.setProperty("user_state", "FE_USER_MODIFY");
Toshio Koidec71b7122014-01-13 15:16:53 -0800189 flowEntryProp.setUserState("FE_USER_MODIFY");
190 } else {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800191System.out.println("About to add a flow entry");
192 flowEntryEntity.operationBegin(DBOperationType.ADD.toString());
193 flowEntryEntity.setProperty("user_state", "FE_USER_ADD");
Toshio Koidec71b7122014-01-13 15:16:53 -0800194 flowEntryProp.setUserState("FE_USER_ADD");
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800195 // NK: iFlowEntry = dbHandler.newFlowEntry(); // toshi memo: addVertex(). setType("flow_entry")
Toshio Koidec71b7122014-01-13 15:16:53 -0800196 //flowObj.addFlowEntry(iFlowEntry); // toshi memo: add.@Adjacency("flow", IN)
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800197 // NK: iFlowEntry.setFlow(flowPathObj); // toshi memo: set.@Adjacency("flow")
198 flowEntryEntity.addEdge(flowPathObj, Direction.OUT, "flow");
Toshio Koidec71b7122014-01-13 15:16:53 -0800199 }
200 } catch (Exception e) {
201 iFlowEntry = null;
202 }
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800203 /* NK:
Toshio Koidec71b7122014-01-13 15:16:53 -0800204 if (iFlowEntry == null) {
205 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created", flowEntry.flowEntryId());
206 dbHandler.rollback();
207 return false;
208 }
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800209 */
Toshio Koidec71b7122014-01-13 15:16:53 -0800210
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800211 flowEntryEntity.setProperty("flow_id", flowEntry.flowEntryId().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800212 // Set the Flow Entry key
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800213 // NK: flowEntryProp.setFlowEntryId(flowEntry.flowEntryId().toString());
214 flowEntryEntity.setProperty("flow_entry_id", flowEntry.flowEntryId().toString());
215
216 flowEntryEntity.setProperty("type", "flow_entry");
217 // NK: flowEntryProp.setType("flow_entry");
Toshio Koidec71b7122014-01-13 15:16:53 -0800218
219 // Set the Flow Entry Edges
220 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString()); // toshi memo: getVertices()
221
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800222 flowEntryEntity.setProperty("idle_timeout", flowEntry.idleTimeout());
223 // NK: flowEntryProp.setIdleTimeout(flowEntry.idleTimeout());
Toshio Koidec71b7122014-01-13 15:16:53 -0800224
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800225 flowEntryEntity.setProperty("hard_timeout", flowEntry.hardTimeout());
226 // NK: flowEntryProp.setHardTimeout(flowEntry.hardTimeout());
227
228 flowEntryEntity.setProperty("switch_dpid", flowEntry.dpid().toString());
229 // NK:flowEntryProp.setSwitchDpid(flowEntry.dpid().toString());
230
231 //NK: iFlowEntry.setSwitch(sw); // toshi memo: set.@Adjacency("switch")
232 flowEntryEntity.addEdge(sw, Direction.OUT, "switch");
Toshio Koidec71b7122014-01-13 15:16:53 -0800233 if (flowEntry.flowEntryMatch().matchInPort()) {
234 IPortObject inport = dbHandler.searchPort(flowEntry.dpid().toString(), flowEntry.flowEntryMatch().inPort().value()); // toshi memo: getVertices()
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800235
236 flowEntryEntity.setProperty("matchInPort", flowEntry.flowEntryMatch().inPort().value());
237 // NK: flowEntryProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
238 flowEntryEntity.addEdge(inport, Direction.OUT, "inport");
239 // NK: iFlowEntry.setInPort(inport); // toshi memo: set.@Adjacency("inport")
Toshio Koidec71b7122014-01-13 15:16:53 -0800240 }
241
242 // Set the Flow Entry attributes
243 if (flowEntry.flowEntryMatch().matchSrcMac()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800244 flowEntryEntity.setProperty("matchSrcMac", flowEntry.flowEntryMatch().srcMac().toString());
245 // NK: flowEntryProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800246 }
247 if (flowEntry.flowEntryMatch().matchDstMac()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800248 flowEntryEntity.setProperty("matchDstMac", flowEntry.flowEntryMatch().dstMac().toString());
249 // NK: flowEntryProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800250 }
251 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800252 flowEntryEntity.setProperty("matchEthernetFrameType", flowEntry.flowEntryMatch().ethernetFrameType());
253 // NK: flowEntryProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
Toshio Koidec71b7122014-01-13 15:16:53 -0800254 }
255 if (flowEntry.flowEntryMatch().matchVlanId()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800256 flowEntryEntity.setProperty("matchVlanId", flowEntry.flowEntryMatch().vlanId());
257 // NK: flowEntryProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
Toshio Koidec71b7122014-01-13 15:16:53 -0800258 }
259 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800260 flowEntryEntity.setProperty("matchVlanPriority", flowEntry.flowEntryMatch().vlanPriority());
261 // NK: flowEntryProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
Toshio Koidec71b7122014-01-13 15:16:53 -0800262 }
263 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800264 flowEntryEntity.setProperty("matchSrcIPv4Net", flowEntry.flowEntryMatch().srcIPv4Net().toString());
265 // NK: flowEntryProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800266 }
267 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800268 flowEntryEntity.setProperty("matchDstIPv4Net", flowEntry.flowEntryMatch().dstIPv4Net().toString());
269 // NK: flowEntryProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800270 }
271 if (flowEntry.flowEntryMatch().matchIpProto()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800272 flowEntryEntity.setProperty("matchIpProto", flowEntry.flowEntryMatch().ipProto());
273 // NK: flowEntryProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
Toshio Koidec71b7122014-01-13 15:16:53 -0800274 }
275 if (flowEntry.flowEntryMatch().matchIpToS()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800276 flowEntryEntity.setProperty("matchIpToS", flowEntry.flowEntryMatch().ipToS());
277 // NK: flowEntryProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
Toshio Koidec71b7122014-01-13 15:16:53 -0800278 }
279 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800280 flowEntryEntity.setProperty("matchSrcTcpUdpPort", flowEntry.flowEntryMatch().srcTcpUdpPort());
281 // NK: flowEntryProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
Toshio Koidec71b7122014-01-13 15:16:53 -0800282 }
283 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800284 flowEntryEntity.setProperty("matchDstTcpUdpPort", flowEntry.flowEntryMatch().dstTcpUdpPort());
285 // NK: flowEntryProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
Toshio Koidec71b7122014-01-13 15:16:53 -0800286 }
287
288 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
289 if (fa.actionOutput() != null) {
290 IPortObject outport = dbHandler.searchPort(flowEntry.dpid().toString(), fa.actionOutput().port().value()); // toshi memo: getVertices()
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800291 flowEntryEntity.setProperty("actionOutputPort", fa.actionOutput().port().value());
292 // NK: flowEntryProp.setActionOutputPort(fa.actionOutput().port().value());
293 flowEntryEntity.addEdge(outport, Direction.OUT, "outport");
294 // NK: iFlowEntry.setOutPort(outport); // set.@Adjacency("outport")
Toshio Koidec71b7122014-01-13 15:16:53 -0800295 }
296 }
297 if (! flowEntry.flowEntryActions().isEmpty()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800298 flowEntryEntity.setProperty("actions", flowEntry.flowEntryActions().toString());
299 // NK: flowEntryProp.setActions(flowEntry.flowEntryActions().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800300 }
301
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800302 flowEntryEntity.setProperty("switch_state", flowEntry.flowEntrySwitchState().toString());
303 // NK: flowEntryProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
304 // NK: flowEntryProp.commitProperties(dbHandler, iFlowEntry); // toshi memo: setProperties()
305 if (updateFlowEntry) {
306 flowEntryEntity.operationEnd(DBOperationType.UPDATE.toString());
307 } else {
308 flowEntryEntity.operationEnd(DBOperationType.ADD.toString());
309 }
310 flowPathEntity.append(flowEntryEntity);
Toshio Koidec71b7122014-01-13 15:16:53 -0800311 }
312
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800313 if (flowPathUpdate) {
314 flowPathEntity.operationEnd(DBOperationType.UPDATE.toString());
315 } else {
316 flowPathEntity.operationEnd(DBOperationType.ADD.toString());
317 }
318 flowPathEntity.persist(dbHandler);
319 // NK:dbHandler.commit();
Toshio Koidec71b7122014-01-13 15:16:53 -0800320 return true;
321 }
322
323 /**
324 * Add a flow.
325 *
326 * @param dbHandler the Graph Database handler to use.
327 * @param flowPath the Flow Path to install.
328 * @return true on success, otherwise false.
329 */
onlab-qa38805cd2013-12-06 20:08:54 -0800330 static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
Toshio Koidec71b7122014-01-13 15:16:53 -0800331 if (useFastAddFlow)
332 return addFlowFast(dbHandler, flowPath);
333
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700334 IFlowPath flowObj = null;
335 boolean found = false;
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800336 long startAddFlow = 0;
337 long endAddFlow = 0;
338 long endSearchExistingFlowPathTime = 0;
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800339 long startCreateNewFlowPathTime = 0;
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800340 long endCreateNewFlowPathTime = 0;
341 long startFollowExistingFlowEntries = 0;
342 long endFollowExistingFlowEntries = 0;
343 long accTimeRemovingFlowEntriesFromFlowPath = 0;
344 long accTimeRemovingFlowEntriesFromDB = 0;
345 long startSettingFlowPathProps = 0;
346 long endSettingFlowPathProps = 0;
347 int numPropsSet = 0;
348 long accTimeAddFlowEntries = 0;
349 int numNewFlowEntries = 0;
350 LinkedList<long[]> flowEntryTimes = new LinkedList<>();
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800351 PerfMon pm = PerfMon.getInstance();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800352
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800353 pm.addflowpath_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700354 try {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800355 if ( measureONOSFlowTimeProp ) {
356 startAddFlow = System.nanoTime();
357 }
yoshi40210942013-12-03 08:21:02 -0800358 flowObj = dbHandler.searchFlowPath(flowPath.flowId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800359 if ( measureONOSFlowTimeProp ) {
360 endSearchExistingFlowPathTime = System.nanoTime();
361 }
yoshi40210942013-12-03 08:21:02 -0800362 if (flowObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700363 found = true;
364 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800365 if ( measureONOSFlowTimeProp ) {
366 startCreateNewFlowPathTime = System.nanoTime();
367 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700368 flowObj = dbHandler.newFlowPath();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800369 if ( measureONOSFlowTimeProp ) {
370 endCreateNewFlowPathTime = System.nanoTime();
371 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700372 }
373 } catch (Exception e) {
374 dbHandler.rollback();
375
376 StringWriter sw = new StringWriter();
377 e.printStackTrace(new PrintWriter(sw));
378 String stacktrace = sw.toString();
379
380 log.error(":addFlow FlowId:{} failed: {}",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800381 flowPath.flowId(),
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700382 stacktrace);
383 return false;
384 }
385 if (flowObj == null) {
386 log.error(":addFlow FlowId:{} failed: Flow object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800387 flowPath.flowId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700388 dbHandler.rollback();
389 return false;
390 }
391
392 //
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800393 // Remove the old Flow Entries
394 //
395 if (found) {
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800396 if ( measureONOSFlowTimeProp ) {
397 startFollowExistingFlowEntries = System.nanoTime();
398 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800399 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800400 if ( measureONOSFlowTimeProp ) {
401 endFollowExistingFlowEntries = System.nanoTime();
402 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800403 LinkedList<IFlowEntry> deleteFlowEntries =
404 new LinkedList<IFlowEntry>();
405 for (IFlowEntry flowEntryObj : flowEntries)
406 deleteFlowEntries.add(flowEntryObj);
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800407 if( measureONOSFlowTimeProp ) {
408 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
409 long start = System.nanoTime();
410 flowObj.removeFlowEntry(flowEntryObj);
411 accTimeRemovingFlowEntriesFromFlowPath += System.nanoTime() - start;
412 start = System.nanoTime();
413 dbHandler.removeFlowEntry(flowEntryObj);
414 accTimeRemovingFlowEntriesFromDB += System.nanoTime() - start;
415 }
416 } else {
417 for (IFlowEntry flowEntryObj : deleteFlowEntries) {
418 flowObj.removeFlowEntry(flowEntryObj);
419 dbHandler.removeFlowEntry(flowEntryObj);
420 }
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800421 }
422 }
423
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800424 if ( measureONOSFlowTimeProp ) {
425 startSettingFlowPathProps = System.nanoTime();
426 }
Toshio Koidea9b25142014-01-10 01:15:57 -0800427
Toshio Koidec71b7122014-01-13 15:16:53 -0800428 FlowPathProperty flowProp = new FlowPathProperty();
Toshio Koidea9b25142014-01-10 01:15:57 -0800429
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800430 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700431 // Set the Flow key:
432 // - flowId
433 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800434 flowProp.setFlowId(flowPath.flowId().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800435 if ( measureONOSFlowTimeProp ) {
436 numPropsSet += 2;
437 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700438
439 //
440 // Set the Flow attributes:
441 // - flowPath.installerId()
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -0700442 // - flowPath.flowPathType()
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -0700443 // - flowPath.flowPathUserState()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700444 // - flowPath.flowPathFlags()
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800445 // - flowPath.idleTimeout()
446 // - flowPath.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700447 // - flowPath.dataPath().srcPort()
448 // - flowPath.dataPath().dstPort()
449 // - flowPath.matchSrcMac()
450 // - flowPath.matchDstMac()
451 // - flowPath.matchEthernetFrameType()
452 // - flowPath.matchVlanId()
453 // - flowPath.matchVlanPriority()
454 // - flowPath.matchSrcIPv4Net()
455 // - flowPath.matchDstIPv4Net()
456 // - flowPath.matchIpProto()
457 // - flowPath.matchIpToS()
458 // - flowPath.matchSrcTcpUdpPort()
459 // - flowPath.matchDstTcpUdpPort()
460 // - flowPath.flowEntryActions()
461 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800462 flowProp.setInstallerId(flowPath.installerId().toString());
463 flowProp.setFlowPathType(flowPath.flowPathType().toString());
464 flowProp.setFlowPathUserState(flowPath.flowPathUserState().toString());
465 flowProp.setFlowPathFlags(flowPath.flowPathFlags().flags());
466 flowProp.setIdleTimeout(flowPath.idleTimeout());
467 flowProp.setHardTimeout(flowPath.hardTimeout());
468 flowProp.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
469 flowProp.setSrcPort(flowPath.dataPath().srcPort().port().value());
470 flowProp.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
471 flowProp.setDstPort(flowPath.dataPath().dstPort().port().value());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800472 if ( measureONOSFlowTimeProp ) {
473 numPropsSet += 10;
474 }
475
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700476 if (flowPath.flowEntryMatch().matchSrcMac()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800477 flowProp.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800478 if ( measureONOSFlowTimeProp ) {
479 ++numPropsSet;
480 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700481 }
482 if (flowPath.flowEntryMatch().matchDstMac()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800483 flowProp.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800484 if ( measureONOSFlowTimeProp ) {
485 ++numPropsSet;
486 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700487 }
488 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800489 flowProp.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800490 if ( measureONOSFlowTimeProp ) {
491 ++numPropsSet;
492 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700493 }
494 if (flowPath.flowEntryMatch().matchVlanId()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800495 flowProp.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800496 if ( measureONOSFlowTimeProp ) {
497 ++numPropsSet;
498 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700499 }
500 if (flowPath.flowEntryMatch().matchVlanPriority()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800501 flowProp.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800502 if ( measureONOSFlowTimeProp ) {
503 ++numPropsSet;
504 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700505 }
506 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800507 flowProp.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800508 if ( measureONOSFlowTimeProp ) {
509 ++numPropsSet;
510 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700511 }
512 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800513 flowProp.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800514 if ( measureONOSFlowTimeProp ) {
515 ++numPropsSet;
516 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700517 }
518 if (flowPath.flowEntryMatch().matchIpProto()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800519 flowProp.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800520 if ( measureONOSFlowTimeProp ) {
521 ++numPropsSet;
522 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700523 }
524 if (flowPath.flowEntryMatch().matchIpToS()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800525 flowProp.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800526 if ( measureONOSFlowTimeProp ) {
527 ++numPropsSet;
528 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700529 }
530 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800531 flowProp.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800532 if ( measureONOSFlowTimeProp ) {
533 ++numPropsSet;
534 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700535 }
536 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800537 flowProp.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800538 if ( measureONOSFlowTimeProp ) {
539 ++numPropsSet;
540 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700541 }
542 if (! flowPath.flowEntryActions().actions().isEmpty()) {
Toshio Koidea9b25142014-01-10 01:15:57 -0800543 flowProp.setActions(flowPath.flowEntryActions().toString());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800544 if ( measureONOSFlowTimeProp ) {
545 ++numPropsSet;
546 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700547 }
Toshio Koidea9b25142014-01-10 01:15:57 -0800548 flowProp.setDataPathSummary(flowPath.dataPath().dataPathSummary());
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800549 if ( measureONOSFlowTimeProp ) {
550 ++numPropsSet;
551 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700552
553 if (found)
Toshio Koidea9b25142014-01-10 01:15:57 -0800554 flowProp.setFlowPathUserState("FP_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700555 else
Toshio Koidea9b25142014-01-10 01:15:57 -0800556 flowProp.setFlowPathUserState("FP_USER_ADD");
557
Toshio Koidec71b7122014-01-13 15:16:53 -0800558 flowProp.commitProperties(dbHandler, flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700559
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800560 if ( measureONOSFlowTimeProp ) {
561 ++numPropsSet;
562 }
563
564 if ( measureONOSFlowTimeProp ) {
565 endSettingFlowPathProps = System.nanoTime();
566 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800567 pm.addflowpath_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700568 // Flow edges:
569 // HeadFE
570
571
572 //
573 // Flow Entries:
574 // flowPath.dataPath().flowEntries()
575 //
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800576 pm.addflowentry_start();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700577 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
Pavlin Radoslavov2fca8d12013-12-04 09:39:06 -0800578 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
579 continue; // Skip: all Flow Entries were deleted earlier
580
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800581 pm.addflowentry_incr();
582
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800583 long startAddFlowEntry = 0, endAddFlowEntry;
584 if( measureONOSFlowTimeProp ) {
585 startAddFlowEntry = System.nanoTime();
586 }
587 IFlowEntry iFlowEntry = addFlowEntry(dbHandler, flowObj, flowEntry);
588 if( measureONOSFlowTimeProp ) {
589 endAddFlowEntry = System.nanoTime();
590 accTimeAddFlowEntries += endAddFlowEntry - startAddFlowEntry;
591
592 flowEntryTimes.addLast( new long[]{flowEntry.flowId().value(), endAddFlowEntry - startAddFlowEntry} );
593 }
594 if ( iFlowEntry == null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700595 dbHandler.rollback();
596 return false;
597 }
598 }
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -0800599 pm.addflowentry_end();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700600 dbHandler.commit();
601
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800602
603 if ( measureONOSFlowTimeProp ) {
604 endAddFlow = System.nanoTime();
605
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800606 log.error("Performance addFlow(_,{}) -- "
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800607 + "GrandTotal: {} "
608 + "only FlowPathTotal: {} "
609 + "searchExistingFlowPath: {} "
610 + "createNewFlowPathTime: {}"
611 + "followExistingFlowEntries: {} "
612 + "accTimeRemovingFlowEntriesFromFlowPath: {} "
613 + "accTimeRemovingFlowEntriesFromDB: {} "
614 + "settingFlowPathProps: {} #Props: {} "
615 + "accFlowEntries: {} #FEs: {}",
616 flowPath.flowId(),
617 (endAddFlow - startAddFlow),
618 (endSettingFlowPathProps - startAddFlow),
619 (endSearchExistingFlowPathTime - startAddFlow),
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800620 (endCreateNewFlowPathTime - startCreateNewFlowPathTime),
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800621 (endFollowExistingFlowEntries - startFollowExistingFlowEntries),
622 (accTimeRemovingFlowEntriesFromFlowPath),
623 (accTimeRemovingFlowEntriesFromDB),
624 (endSettingFlowPathProps - startSettingFlowPathProps), numPropsSet,
625 accTimeAddFlowEntries, numNewFlowEntries
626 );
627
628 // Each FlowEntries
629 final String strFlowId = flowPath.flowId().toString();
630 for ( long[] idFE_Time : flowEntryTimes ) {
Yuta HIGUCHI0b4fbaf2014-01-04 22:23:05 -0800631 log.error("Performance addFlowEntry(_,{},{})@addFlow -- FlowEntryTotal: {}",
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800632 strFlowId,
633 "0x" + Long.toHexString(idFE_Time[0]),
634 idFE_Time[1]);
635 }
636 }
637
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700638 return true;
639 }
640
641 /**
642 * Add a flow entry to the Network MAP.
643 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700644 * @param dbHandler the Graph Database handler to use.
645 * @param flowObj the corresponding Flow Path object for the Flow Entry.
646 * @param flowEntry the Flow Entry to install.
647 * @return the added Flow Entry object on success, otherwise null.
648 */
onlab-qa38805cd2013-12-06 20:08:54 -0800649 static IFlowEntry addFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700650 IFlowPath flowObj,
651 FlowEntry flowEntry) {
652 // Flow edges
653 // HeadFE (TODO)
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800654 long startAddFlowEntry = 0;
655 long endAddFlowEntry = 0;
656
657 long endSearchFlowEntry = 0;
658
659 long startCreateNewFlowEntry = 0;
660 long endCreateNewFlowEntry = 0;
661
662 long startSetProperties = 0;
663 long endSetProperties = 0;
664 int numProperties = 0;
665
666 long startSearchSwitch = 0;
667 long endSearchSwitch = 0;
668
669 long startAddEdgeToSwitch =0;
670 long endAddEdgeToSwitch =0;
671
672 long startSearchInPort = 0;
673 long endSearchInPort = 0;
674
675 long startAddEdgeToInPort =0;
676 long endAddEdgeToInPort =0;
677
678 long startSearchOutPort = 0;
679 long endSearchOutPort = 0;
680
681 long startAddEdgeToOutPort =0;
682 long endAddEdgeToOutPort =0;
683
684 long startAddEdgeBetweenFlowPath = 0;
685 long endAddEdgeBetweenFlowPath = 0;
686
687 if (measureONOSFlowEntryTimeProp) {
688 startAddFlowEntry = System.nanoTime();
689 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700690
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700691 IFlowEntry flowEntryObj = null;
692 boolean found = false;
693 try {
Yuta HIGUCHIc27a6c92014-01-07 11:51:11 -0800694 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
695 if (measureONOSFlowEntryTimeProp) {
696 endSearchFlowEntry = System.nanoTime();
697 }
698 if (flowEntryObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700699 found = true;
700 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800701 if (measureONOSFlowEntryTimeProp) {
702 startCreateNewFlowEntry = System.nanoTime();
703 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700704 flowEntryObj = dbHandler.newFlowEntry();
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800705 if (measureONOSFlowEntryTimeProp) {
706 endCreateNewFlowEntry = System.nanoTime();
707 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700708 }
709 } catch (Exception e) {
710 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800711 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700712 return null;
713 }
714 if (flowEntryObj == null) {
715 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800716 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700717 return null;
718 }
719
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800720 if (measureONOSFlowEntryTimeProp) {
721 startSetProperties = System.nanoTime();
722 }
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800723
Toshio Koidec71b7122014-01-13 15:16:53 -0800724 FlowEntryProperty flowProp = new FlowEntryProperty();
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800725
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700726 //
727 // Set the Flow Entry key:
728 // - flowEntry.flowEntryId()
729 //
Toshio Koide3f233542014-01-07 14:19:09 -0800730 flowProp.setFlowEntryId(flowEntry.flowEntryId().toString());
731 flowProp.setType("flow_entry");
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800732 if (measureONOSFlowEntryTimeProp) {
733 numProperties += 2;
734 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700735
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800736 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700737 // Set the Flow Entry Edges and attributes:
738 // - Switch edge
739 // - InPort edge
740 // - OutPort edge
741 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800742 // - flowEntry.idleTimeout()
743 // - flowEntry.hardTimeout()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700744 // - flowEntry.dpid()
745 // - flowEntry.flowEntryUserState()
746 // - flowEntry.flowEntrySwitchState()
747 // - flowEntry.flowEntryErrorState()
748 // - flowEntry.matchInPort()
749 // - flowEntry.matchSrcMac()
750 // - flowEntry.matchDstMac()
751 // - flowEntry.matchEthernetFrameType()
752 // - flowEntry.matchVlanId()
753 // - flowEntry.matchVlanPriority()
754 // - flowEntry.matchSrcIPv4Net()
755 // - flowEntry.matchDstIPv4Net()
756 // - flowEntry.matchIpProto()
757 // - flowEntry.matchIpToS()
758 // - flowEntry.matchSrcTcpUdpPort()
759 // - flowEntry.matchDstTcpUdpPort()
760 // - flowEntry.actionOutputPort()
761 // - flowEntry.actions()
762 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800763 if (measureONOSFlowEntryTimeProp) {
764 startSearchSwitch = System.nanoTime();
765 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700766 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800767 if (measureONOSFlowEntryTimeProp) {
768 endSearchSwitch = System.nanoTime();
769 }
770
Toshio Koide3f233542014-01-07 14:19:09 -0800771 flowProp.setIdleTimeout(flowEntry.idleTimeout());
772 flowProp.setHardTimeout(flowEntry.hardTimeout());
773 flowProp.setSwitchDpid(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800774 if (measureONOSFlowEntryTimeProp) {
775 numProperties += 3;
776 }
777
778 if (measureONOSFlowEntryTimeProp) {
779 startAddEdgeToSwitch = System.nanoTime();
780 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700781 flowEntryObj.setSwitch(sw);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800782 if (measureONOSFlowEntryTimeProp) {
783 endAddEdgeToSwitch = System.nanoTime();
784 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700785 if (flowEntry.flowEntryMatch().matchInPort()) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800786 if (measureONOSFlowEntryTimeProp) {
787 startSearchInPort = System.nanoTime();
788 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700789 IPortObject inport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800790 dbHandler.searchPort(flowEntry.dpid().toString(),
791 flowEntry.flowEntryMatch().inPort().value());
792 if (measureONOSFlowEntryTimeProp) {
793 endSearchInPort = System.nanoTime();
794 }
795
Toshio Koide3f233542014-01-07 14:19:09 -0800796 flowProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800797 if (measureONOSFlowEntryTimeProp) {
798 ++numProperties;
799 }
800
801 if (measureONOSFlowEntryTimeProp) {
802 startAddEdgeToInPort = System.nanoTime();
803 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700804 flowEntryObj.setInPort(inport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800805 if (measureONOSFlowEntryTimeProp) {
806 endAddEdgeToInPort = System.nanoTime();
807 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700808 }
809 if (flowEntry.flowEntryMatch().matchSrcMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800810 flowProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800811 if (measureONOSFlowEntryTimeProp) {
812 ++numProperties;
813 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700814 }
815 if (flowEntry.flowEntryMatch().matchDstMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800816 flowProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800817 if (measureONOSFlowEntryTimeProp) {
818 ++numProperties;
819 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700820 }
821 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800822 flowProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800823 if (measureONOSFlowEntryTimeProp) {
824 ++numProperties;
825 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700826 }
827 if (flowEntry.flowEntryMatch().matchVlanId()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800828 flowProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800829 if (measureONOSFlowEntryTimeProp) {
830 ++numProperties;
831 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700832 }
833 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800834 flowProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800835 if (measureONOSFlowEntryTimeProp) {
836 ++numProperties;
837 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700838 }
839 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800840 flowProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800841 if (measureONOSFlowEntryTimeProp) {
842 ++numProperties;
843 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700844 }
845 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800846 flowProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800847 if (measureONOSFlowEntryTimeProp) {
848 ++numProperties;
849 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700850 }
851 if (flowEntry.flowEntryMatch().matchIpProto()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800852 flowProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800853 if (measureONOSFlowEntryTimeProp) {
854 ++numProperties;
855 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700856 }
857 if (flowEntry.flowEntryMatch().matchIpToS()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800858 flowProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800859 if (measureONOSFlowEntryTimeProp) {
860 ++numProperties;
861 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700862 }
863 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800864 flowProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800865 if (measureONOSFlowEntryTimeProp) {
866 ++numProperties;
867 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700868 }
869 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800870 flowProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800871 if (measureONOSFlowEntryTimeProp) {
872 ++numProperties;
873 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700874 }
875
876 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
877 if (fa.actionOutput() != null) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800878 if (measureONOSFlowEntryTimeProp) {
879 if ( startSearchOutPort != 0 ) log.error("Performance addFlowEntry(_,{},{}) -- Multiple output port action unexpected.", flowEntry.flowId(), flowEntry.flowEntryId());
880 startSearchOutPort = System.nanoTime();
881 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700882 IPortObject outport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800883 dbHandler.searchPort(flowEntry.dpid().toString(),
884 fa.actionOutput().port().value());
885 if (measureONOSFlowEntryTimeProp) {
886 endSearchOutPort = System.nanoTime();
887 }
888
Toshio Koide3f233542014-01-07 14:19:09 -0800889 flowProp.setActionOutputPort(fa.actionOutput().port().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800890 if (measureONOSFlowEntryTimeProp) {
891 ++numProperties;
892 }
893
894 if (measureONOSFlowEntryTimeProp) {
895 startAddEdgeToOutPort = System.nanoTime();
896 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700897 flowEntryObj.setOutPort(outport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800898 if (measureONOSFlowEntryTimeProp) {
899 endAddEdgeToOutPort = System.nanoTime();
900 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700901 }
902 }
903 if (! flowEntry.flowEntryActions().isEmpty()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800904 flowProp.setActions(flowEntry.flowEntryActions().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800905 if (measureONOSFlowEntryTimeProp) {
906 ++numProperties;
907 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700908 }
909
910 // TODO: Hacks with hard-coded state names!
911 if (found)
Toshio Koide3f233542014-01-07 14:19:09 -0800912 flowProp.setUserState("FE_USER_MODIFY");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700913 else
Toshio Koide3f233542014-01-07 14:19:09 -0800914 flowProp.setUserState("FE_USER_ADD");
915 flowProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800916 if (measureONOSFlowEntryTimeProp) {
917 numProperties += 2;
918 }
Toshio Koidec71b7122014-01-13 15:16:53 -0800919 flowProp.commitProperties(dbHandler, flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700920 //
921 // TODO: Take care of the FlowEntryErrorState.
922 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800923 if (measureONOSFlowEntryTimeProp) {
924 endSetProperties = System.nanoTime();
925 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700926
927 // Flow Entries edges:
928 // Flow
929 // NextFE (TODO)
930 if (! found) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800931 if (measureONOSFlowEntryTimeProp) {
932 startAddEdgeBetweenFlowPath = System.nanoTime();
933 }
Toshio Koidec71b7122014-01-13 15:16:53 -0800934 //flowObj.addFlowEntry(flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700935 flowEntryObj.setFlow(flowObj);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800936 if (measureONOSFlowEntryTimeProp) {
937 endAddEdgeBetweenFlowPath = System.nanoTime();
938 }
939 }
940 if (measureONOSFlowEntryTimeProp) {
941 endAddFlowEntry = System.nanoTime();
942
943 log.error("Performance addFlowEntry(_,{},{}) -- "
944 + "GrandTotal: {} "
945 + "SearchExistingFE: {} "
946 + "CreateNewFE: {} "
947 + "SetProp+Edge: {} #Props: {} "
948 + "SearchSwitch: {} "
949 + "AddEdgeToSwitch: {} "
950 + "SearchInPort: {} "
951 + "AddEdgeToInPort: {} "
952 + "SearchOutPort: {} "
953 + "AddEdgeToOutPort: {} "
954 + "AddEdgeBetweenFlowPath: {} "
955 , flowEntry.flowId(), flowEntry.flowEntryId()
956 , endAddFlowEntry - startAddFlowEntry
957 , endSearchFlowEntry - startAddFlowEntry
958 , endCreateNewFlowEntry - startCreateNewFlowEntry
959 , endSetProperties - startSetProperties, numProperties
960 , endSearchSwitch - startSearchSwitch
961 , endAddEdgeToSwitch - startAddEdgeToSwitch
962 , endSearchInPort - startSearchInPort
963 , endAddEdgeToInPort - startAddEdgeToInPort
964 , endSearchOutPort - startSearchOutPort
965 , endAddEdgeToOutPort - startAddEdgeToOutPort
966 , endAddEdgeBetweenFlowPath - startAddEdgeBetweenFlowPath
967 );
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700968 }
969
970 return flowEntryObj;
971 }
972
973 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700974 * Delete a flow entry from the Network MAP.
975 *
976 * @param dbHandler the Graph Database handler to use.
977 * @param flowObj the corresponding Flow Path object for the Flow Entry.
978 * @param flowEntry the Flow Entry to delete.
979 * @return true on success, otherwise false.
980 */
yoshitomob292c622013-11-23 14:35:58 -0800981 static boolean deleteFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700982 IFlowPath flowObj,
983 FlowEntry flowEntry) {
984 IFlowEntry flowEntryObj = null;
985 try {
986 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
987 } catch (Exception e) {
988 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800989 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700990 return false;
991 }
992 //
993 // TODO: Don't print an error for now, because multiple controller
994 // instances might be deleting the same flow entry.
995 //
996 /*
997 if (flowEntryObj == null) {
998 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800999 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -07001000 return false;
1001 }
1002 */
1003 if (flowEntryObj == null)
1004 return true;
1005
1006 flowObj.removeFlowEntry(flowEntryObj);
1007 dbHandler.removeFlowEntry(flowEntryObj);
1008 return true;
1009 }
1010
1011 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001012 * Delete all previously added flows.
1013 *
1014 * @param dbHandler the Graph Database handler to use.
1015 * @return true on success, otherwise false.
1016 */
yoshitomob292c622013-11-23 14:35:58 -08001017 static boolean deleteAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001018 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
1019 for (IFlowPath flowPathObj : allFlowPaths) {
1020 if (flowPathObj == null)
1021 continue;
Yuta HIGUCHI53794052014-01-10 16:49:41 -08001022 deleteIFlowPath(dbHandler, flowPathObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001023 }
1024
1025 return true;
1026 }
1027
1028 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -08001029 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001030 *
1031 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -08001032 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001033 * @return true on success, otherwise false.
1034 */
yoshitomob292c622013-11-23 14:35:58 -08001035 static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001036 IFlowPath flowObj = null;
1037 try {
1038 flowObj = dbHandler.searchFlowPath(flowId);
1039 } catch (Exception e) {
1040 // TODO: handle exceptions
1041 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -08001042 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001043 return false;
1044 }
1045 if (flowObj == null) {
1046 dbHandler.commit();
1047 return true; // OK: No such flow
1048 }
1049
Yuta HIGUCHI53794052014-01-10 16:49:41 -08001050 deleteIFlowPath(dbHandler, flowObj);
1051
1052 return true;
1053 }
1054
1055 private static void deleteIFlowPath(DBOperation dbHandler, IFlowPath flowObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001056 //
1057 // Remove all Flow Entries
1058 //
1059 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
1060 for (IFlowEntry flowEntryObj : flowEntries) {
1061 flowObj.removeFlowEntry(flowEntryObj);
1062 dbHandler.removeFlowEntry(flowEntryObj);
1063 }
1064 // Remove the Flow itself
1065 dbHandler.removeFlowPath(flowObj);
Nick Karanatsios758df8d2014-01-14 22:16:32 -08001066 dbHandler.commit();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001067 }
1068
1069 /**
1070 * Get a previously added flow.
1071 *
1072 * @param dbHandler the Graph Database handler to use.
1073 * @param flowId the Flow ID of the flow to get.
1074 * @return the Flow Path if found, otherwise null.
1075 */
yoshitomob292c622013-11-23 14:35:58 -08001076 static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001077 IFlowPath flowObj = null;
1078 try {
1079 flowObj = dbHandler.searchFlowPath(flowId);
1080 } catch (Exception e) {
1081 // TODO: handle exceptions
1082 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -08001083 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001084 return null;
1085 }
1086 if (flowObj == null) {
1087 dbHandler.commit();
1088 return null; // Flow not found
1089 }
1090
1091 //
1092 // Extract the Flow state
1093 //
1094 FlowPath flowPath = extractFlowPath(flowObj);
1095 dbHandler.commit();
1096
1097 return flowPath;
1098 }
1099
1100 /**
1101 * Get all installed flows by all installers.
1102 *
1103 * @param dbHandler the Graph Database handler to use.
1104 * @return the Flow Paths if found, otherwise null.
1105 */
yoshitomob292c622013-11-23 14:35:58 -08001106 static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001107 Iterable<IFlowPath> flowPathsObj = null;
1108 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
1109
1110 try {
1111 flowPathsObj = dbHandler.getAllFlowPaths();
1112 } catch (Exception e) {
1113 // TODO: handle exceptions
1114 dbHandler.rollback();
1115 log.error(":getAllFlowPaths failed");
1116 return flowPaths;
1117 }
1118 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
1119 dbHandler.commit();
1120 return flowPaths; // No Flows found
1121 }
1122
1123 for (IFlowPath flowObj : flowPathsObj) {
1124 //
1125 // Extract the Flow state
1126 //
1127 FlowPath flowPath = extractFlowPath(flowObj);
1128 if (flowPath != null)
1129 flowPaths.add(flowPath);
1130 }
1131
1132 dbHandler.commit();
1133
1134 return flowPaths;
1135 }
1136
1137 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001138 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
1139 *
1140 * @param flowObj the object to extract the Flow Path State from.
1141 * @return the extracted Flow Path State.
1142 */
1143 private static FlowPath extractFlowPath(IFlowPath flowObj) {
1144 //
1145 // Extract the Flow state
1146 //
Toshio Koidea9b25142014-01-10 01:15:57 -08001147 log.info("extractFlowPath: start");
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001148 String flowIdStr;
1149 String installerIdStr;
1150 String flowPathType;
1151 String flowPathUserState;
1152 Long flowPathFlags;
1153 Integer idleTimeout;
1154 Integer hardTimeout;
1155 String srcSwitchStr;
1156 Short srcPortShort;
1157 String dstSwitchStr;
1158 Short dstPortShort;
1159
1160 if ( flowObj.asVertex() instanceof RamCloudVertex ) {
1161 RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
1162 Map<String,Object> propMap = v.getProperties();
1163
1164 flowIdStr = (String) propMap.get("flow_id");
1165 installerIdStr = (String) propMap.get("installer_id");
1166 flowPathType = (String) propMap.get("flow_path_type");
1167 flowPathUserState = (String) propMap.get("user_state");
1168 flowPathFlags = (Long)propMap.get("flow_path_flags");
1169 idleTimeout = (Integer) propMap.get("idle_timeout");
1170 hardTimeout = (Integer) propMap.get("hard_timeout");
1171 srcSwitchStr = (String) propMap.get("src_switch");
1172 srcPortShort = (Short)propMap.get("src_port");
1173 dstSwitchStr = (String) propMap.get("dst_switch");
1174 dstPortShort = (Short)propMap.get("dst_port");
1175 } else {
1176 flowIdStr = flowObj.getFlowId();
1177 installerIdStr = flowObj.getInstallerId();
1178 flowPathType = flowObj.getFlowPathType();
1179 flowPathUserState = flowObj.getFlowPathUserState();
1180 flowPathFlags = flowObj.getFlowPathFlags();
1181 idleTimeout = flowObj.getIdleTimeout();
1182 hardTimeout = flowObj.getHardTimeout();
1183 srcSwitchStr = flowObj.getSrcSwitch();
1184 srcPortShort = flowObj.getSrcPort();
1185 dstSwitchStr = flowObj.getDstSwitch();
1186 dstPortShort = flowObj.getDstPort();
1187 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001188
1189 if ((flowIdStr == null) ||
1190 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -07001191 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -07001192 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001193 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001194 (idleTimeout == null) ||
1195 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001196 (srcSwitchStr == null) ||
1197 (srcPortShort == null) ||
1198 (dstSwitchStr == null) ||
1199 (dstPortShort == null)) {
Toshio Koidea9b25142014-01-10 01:15:57 -08001200 // TODO: A work-around, because of some bogus database objects
1201 log.error("extractFlowPath: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001202 return null;
1203 }
1204
1205 FlowPath flowPath = new FlowPath();
1206 flowPath.setFlowId(new FlowId(flowIdStr));
1207 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -07001208 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -07001209 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001210 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001211 flowPath.setIdleTimeout(idleTimeout);
1212 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001213 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
1214 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
1215 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
1216 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
1217 //
1218 // Extract the match conditions common for all Flow Entries
1219 //
1220 {
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001221 FlowEntryMatch match = extractMatch(flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001222
1223 flowPath.setFlowEntryMatch(match);
1224 }
1225 //
1226 // Extract the actions for the first Flow Entry
1227 //
1228 {
1229 String actionsStr = flowObj.getActions();
1230 if (actionsStr != null) {
1231 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
1232 flowPath.setFlowEntryActions(flowEntryActions);
1233 }
1234 }
1235
1236 //
1237 // Extract all Flow Entries
1238 //
1239 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
1240 for (IFlowEntry flowEntryObj : flowEntries) {
1241 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
1242 if (flowEntry == null)
1243 continue;
1244 flowPath.dataPath().flowEntries().add(flowEntry);
1245 }
1246
Toshio Koidea9b25142014-01-10 01:15:57 -08001247 log.info("extractFlowPath: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001248 return flowPath;
1249 }
1250
1251 /**
1252 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
1253 *
1254 * @param flowEntryObj the object to extract the Flow Entry State from.
1255 * @return the extracted Flow Entry State.
1256 */
Brian O'Connora8e49802013-10-30 20:49:59 -07001257 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Toshio Koidea9b25142014-01-10 01:15:57 -08001258 log.info("extractFlowEntry: start");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001259 IFlowPath flowObj = flowEntryObj.getFlow();
Toshio Koidea9b25142014-01-10 01:15:57 -08001260 if (flowObj == null) {
1261 log.error("extractFlowEntry: no flowPath exists");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001262 return null;
Toshio Koidea9b25142014-01-10 01:15:57 -08001263 }
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001264
1265 String flowIdStr = flowObj.getFlowId();
1266 //
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001267 String flowEntryIdStr;
1268 Integer idleTimeout;
1269 Integer hardTimeout;
1270 String switchDpidStr;
1271 String userState;
1272 String switchState;
1273 if ( flowEntryObj.asVertex() instanceof RamCloudVertex ) {
1274 RamCloudVertex v = (RamCloudVertex)flowEntryObj.asVertex();
1275 Map<String,Object> propMap = v.getProperties();
1276
1277 flowEntryIdStr = (String) propMap.get("flow_entry_id");
1278 idleTimeout = (Integer) propMap.get("idle_timeout");
1279 hardTimeout = (Integer) propMap.get("hard_timeout");
1280 switchDpidStr = (String) propMap.get("switch_dpid");
1281 userState = (String) propMap.get("user_state");
1282 switchState = (String) propMap.get("switch_state");
1283 } else {
1284 flowEntryIdStr = flowEntryObj.getFlowEntryId();
1285 idleTimeout = flowEntryObj.getIdleTimeout();
1286 hardTimeout = flowEntryObj.getHardTimeout();
1287 switchDpidStr = flowEntryObj.getSwitchDpid();
1288 userState = flowEntryObj.getUserState();
1289 switchState = flowEntryObj.getSwitchState();
1290 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001291
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001292 if ((flowIdStr == null) ||
1293 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001294 (idleTimeout == null) ||
1295 (hardTimeout == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001296 (switchDpidStr == null) ||
1297 (userState == null) ||
1298 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -07001299 // TODO: A work-around, because of some bogus database objects
Toshio Koidea9b25142014-01-10 01:15:57 -08001300 log.error("extractFlowEntry: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001301 return null;
1302 }
1303
1304 FlowEntry flowEntry = new FlowEntry();
1305 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001306 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001307 flowEntry.setDpid(new Dpid(switchDpidStr));
yoshia97632b2013-12-17 15:46:08 -08001308 flowEntry.setIdleTimeout(idleTimeout);
1309 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001310
1311 //
1312 // Extract the match conditions
1313 //
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001314 FlowEntryMatch match = extractMatch(flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001315 flowEntry.setFlowEntryMatch(match);
1316
1317 //
1318 // Extract the actions
1319 //
1320 FlowEntryActions actions = new FlowEntryActions();
1321 String actionsStr = flowEntryObj.getActions();
1322 if (actionsStr != null)
1323 actions = new FlowEntryActions(actionsStr);
1324 flowEntry.setFlowEntryActions(actions);
1325 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
1326 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
1327 //
1328 // TODO: Take care of FlowEntryErrorState.
1329 //
Toshio Koidea9b25142014-01-10 01:15:57 -08001330 log.info("extractFlowEntry: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001331 return flowEntry;
1332 }
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001333
1334 /**
1335 * Extract FlowEntryMatch from IFlowPath or IFlowEntry
1336 * @param flowObj : either IFlowPath or IFlowEntry
1337 * @return extracted Match info
1338 */
1339 private static FlowEntryMatch extractMatch(IBaseObject flowObj) {
1340 FlowEntryMatch match = new FlowEntryMatch();
1341
1342 Short matchInPort = null; // Only for IFlowEntry
1343 String matchSrcMac = null;
1344 String matchDstMac = null;
1345 Short matchEthernetFrameType = null;
1346 Short matchVlanId = null;
1347 Byte matchVlanPriority = null;
1348 String matchSrcIPv4Net = null;
1349 String matchDstIPv4Net = null;
1350 Byte matchIpProto = null;
1351 Byte matchIpToS = null;
1352 Short matchSrcTcpUdpPort = null;
1353 Short matchDstTcpUdpPort = null;
1354
1355 if ( flowObj.asVertex() instanceof RamCloudVertex ) {
1356 RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
1357 Map<String,Object> propMap = v.getProperties();
1358 matchInPort = (Short) propMap.get("matchInPort");
1359 matchSrcMac = (String) propMap.get("matchSrcMac");
1360 matchDstMac = (String) propMap.get("matchDstMac");
1361 matchEthernetFrameType = (Short) propMap.get("matchEthernetFrameType");
1362 matchVlanId = (Short) propMap.get("matchVlanId");
1363 matchVlanPriority = (Byte) propMap.get("matchVlanPriority");
1364 matchSrcIPv4Net = (String) propMap.get("matchSrcIPv4Net");
1365 matchDstIPv4Net = (String) propMap.get("matchDstIPv4Net");
1366 matchIpProto = (Byte) propMap.get("matchIpProto");
1367 matchIpToS = (Byte) propMap.get("matchIpToS");
1368 matchSrcTcpUdpPort = (Short) propMap.get("matchSrcTcpUdpPort");
1369 matchDstTcpUdpPort = (Short) propMap.get("matchDstTcpUdpPort");
1370 } else {
1371 if (flowObj instanceof IFlowEntry ){
1372 IFlowEntry flowEntry = (IFlowEntry) flowObj;
1373 matchInPort = flowEntry.getMatchInPort();
1374 matchSrcMac = flowEntry.getMatchSrcMac();
1375 matchDstMac = flowEntry.getMatchDstMac();
1376 matchEthernetFrameType = flowEntry.getMatchEthernetFrameType();
1377 matchVlanId = flowEntry.getMatchVlanId();
1378 matchVlanPriority = flowEntry.getMatchVlanPriority();
1379 matchSrcIPv4Net = flowEntry.getMatchSrcIPv4Net();
1380 matchDstIPv4Net = flowEntry.getMatchDstIPv4Net();
1381 matchIpProto = flowEntry.getMatchIpProto();
1382 matchIpToS = flowEntry.getMatchIpToS();
1383 matchSrcTcpUdpPort = flowEntry.getMatchSrcTcpUdpPort();
1384 matchDstTcpUdpPort = flowEntry.getMatchDstTcpUdpPort();
1385 } else if(flowObj instanceof IFlowPath) {
1386 IFlowPath flowPath = (IFlowPath) flowObj;
1387 matchSrcMac = flowPath.getMatchSrcMac();
1388 matchDstMac = flowPath.getMatchDstMac();
1389 matchEthernetFrameType = flowPath.getMatchEthernetFrameType();
1390 matchVlanId = flowPath.getMatchVlanId();
1391 matchVlanPriority = flowPath.getMatchVlanPriority();
1392 matchSrcIPv4Net = flowPath.getMatchSrcIPv4Net();
1393 matchDstIPv4Net = flowPath.getMatchDstIPv4Net();
1394 matchIpProto = flowPath.getMatchIpProto();
1395 matchIpToS = flowPath.getMatchIpToS();
1396 matchSrcTcpUdpPort = flowPath.getMatchSrcTcpUdpPort();
1397 matchDstTcpUdpPort = flowPath.getMatchDstTcpUdpPort();
1398 }
1399 }
1400
1401 if (matchInPort != null)
1402 match.enableInPort(new Port(matchInPort));
1403 if (matchSrcMac != null)
1404 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
1405 if (matchDstMac != null)
1406 match.enableDstMac(MACAddress.valueOf(matchDstMac));
1407 if (matchEthernetFrameType != null)
1408 match.enableEthernetFrameType(matchEthernetFrameType);
1409 if (matchVlanId != null)
1410 match.enableVlanId(matchVlanId);
1411 if (matchVlanPriority != null)
1412 match.enableVlanPriority(matchVlanPriority);
1413 if (matchSrcIPv4Net != null)
1414 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
1415 if (matchDstIPv4Net != null)
1416 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
1417 if (matchIpProto != null)
1418 match.enableIpProto(matchIpProto);
1419 if (matchIpToS != null)
1420 match.enableIpToS(matchIpToS);
1421 if (matchSrcTcpUdpPort != null)
1422 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
1423 if (matchDstTcpUdpPort != null)
1424 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
1425 return match;
1426 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001427}