blob: aee2ecb7917a090b04dfac88b9a665a2243a0c74 [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 Radoslavovf3f23bb2014-01-10 13:02:33 -08007import java.util.Collection;
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08008import java.util.LinkedList;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08009import java.util.Map;
10
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -080011import net.floodlightcontroller.core.IOFSwitch;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070012import net.floodlightcontroller.util.MACAddress;
yoshitomob292c622013-11-23 14:35:58 -080013import net.onrc.onos.graph.DBOperation;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -080014import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070015import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
16import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
17import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
18import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
19import net.onrc.onos.ofcontroller.util.*;
20
21import org.slf4j.Logger;
22import org.slf4j.LoggerFactory;
23
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080024import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -080025import com.tinkerpop.blueprints.impls.ramcloud.RamCloudVertex;
Yuta HIGUCHIdad0a2d2014-01-06 15:52:52 -080026
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070027/**
28 * Class for performing Flow-related operations on the Database.
29 */
Pavlin Radoslavov6bfaea62013-12-03 14:55:57 -080030public class FlowDatabaseOperation {
Yuta HIGUCHI6ac8d182013-10-22 15:24:56 -070031 private final static Logger log = LoggerFactory.getLogger(FlowDatabaseOperation.class);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -080032 private static final boolean measureONOSFlowTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlow", "0")) != 0;
33 private static final boolean measureONOSFlowEntryTimeProp = Long.valueOf(System.getProperty("benchmark.measureONOSFlowEntry", "0")) != 0;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070034
35 /**
Nick Karanatsios1e802382014-01-23 11:12:16 -080036 * Add a flow by batching all flow path properties and flow entries together.
37 * This is done for performance reasons.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070038 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070039 * @param dbHandler the Graph Database handler to use.
40 * @param flowPath the Flow Path to install.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -070041 * @return true on success, otherwise false.
42 */
Toshio Koidec71b7122014-01-13 15:16:53 -080043 static boolean addFlowFast(DBOperation dbHandler, FlowPath flowPath) {
Nick Karanatsios1e802382014-01-23 11:12:16 -080044 IFlowPath flowPathObj;
Toshio Koidec71b7122014-01-13 15:16:53 -080045 FlowPathProperty flowProp = new FlowPathProperty();
Nick Karanatsios758df8d2014-01-14 22:16:32 -080046 FlowEntity flowPathEntity = new FlowEntity();
47 boolean flowPathUpdate = false;
Toshio Koidec71b7122014-01-13 15:16:53 -080048
Nick Karanatsios1e802382014-01-23 11:12:16 -080049 flowPathObj = dbHandler.searchFlowPath(flowPath.flowId()); // getVertices("flow_id")
Toshio Koidec71b7122014-01-13 15:16:53 -080050 if (flowPathObj == null) {
51 try {
Nick Karanatsios758df8d2014-01-14 22:16:32 -080052 flowPathEntity.operationBegin(DBOperationType.ADD.toString());
Nick Karanatsios1e802382014-01-23 11:12:16 -080053 flowPathObj = dbHandler.newFlowPath();
Toshio Koidec71b7122014-01-13 15:16:53 -080054 } catch (Exception e) {
55 flowPathObj = null;
56 StringWriter sw = new StringWriter();
57 e.printStackTrace(new PrintWriter(sw));
58 log.error(":addFlow FlowId:{} failed: {}", flowPath.flowId(), sw.toString());
59 }
Nick Karanatsios758df8d2014-01-14 22:16:32 -080060 flowPathEntity.setProperty("user_state", "FP_USER_ADD");
Toshio Koidec71b7122014-01-13 15:16:53 -080061 flowProp.setFlowPathUserState("FP_USER_ADD");
62 } else {
Nick Karanatsios758df8d2014-01-14 22:16:32 -080063 flowPathUpdate = true;
Toshio Koidec71b7122014-01-13 15:16:53 -080064 // Remove the old Flow Entries (this is special for RAMCloud)
Nick Karanatsios1e802382014-01-23 11:12:16 -080065 for (IFlowEntry flowEntryObj : flowPathObj.getFlowEntries()) { // get.@Adjacency("flow", IN)
Nick Karanatsios758df8d2014-01-14 22:16:32 -080066 flowPathEntity.operationBegin(DBOperationType.REMOVE.toString());
Nick Karanatsios1e802382014-01-23 11:12:16 -080067 dbHandler.removeFlowEntry(flowEntryObj); // removeVertex()
Nick Karanatsios758df8d2014-01-14 22:16:32 -080068 flowPathEntity.operationEnd(DBOperationType.REMOVE.toString());
Toshio Koidec71b7122014-01-13 15:16:53 -080069 }
Nick Karanatsios758df8d2014-01-14 22:16:32 -080070 flowPathEntity.operationBegin(DBOperationType.UPDATE.toString());
71 flowPathEntity.setProperty("user_state", "FP_USER_ADD");
Toshio Koidec71b7122014-01-13 15:16:53 -080072 flowProp.setFlowPathUserState("FP_USER_MODIFY");
73 }
74 if (flowPathObj == null) {
75 log.error(":addFlow FlowId:{} failed: Flow object not created", flowPath.flowId());
76 dbHandler.rollback();
Toshio Koidec71b7122014-01-13 15:16:53 -080077 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 flowPathEntity.setProperty("installer_id", flowPath.installerId().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -080086 flowProp.setInstallerId(flowPath.installerId().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -080087
88 flowPathEntity.setProperty("flow_path_type", flowPath.flowPathType().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -080089 flowProp.setFlowPathType(flowPath.flowPathType().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -080090
91 flowPathEntity.setProperty("user_state", flowPath.flowPathUserState().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -080092 flowProp.setFlowPathUserState(flowPath.flowPathUserState().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -080093
94
95 flowPathEntity.setProperty("flow_path_flags", flowPath.flowPathFlags().flags());
Toshio Koidec71b7122014-01-13 15:16:53 -080096 flowProp.setFlowPathFlags(flowPath.flowPathFlags().flags());
Nick Karanatsios758df8d2014-01-14 22:16:32 -080097
98 flowPathEntity.setProperty("idle_timeout", flowPath.idleTimeout());
Toshio Koidec71b7122014-01-13 15:16:53 -080099 flowProp.setIdleTimeout(flowPath.idleTimeout());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800100
101 flowPathEntity.setProperty("hard_timeout", flowPath.hardTimeout());
Toshio Koidec71b7122014-01-13 15:16:53 -0800102 flowProp.setHardTimeout(flowPath.hardTimeout());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800103
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800104 flowPathEntity.setProperty("priority", flowPath.priority());
105 flowProp.setPriority(flowPath.priority());
106
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800107 flowPathEntity.setProperty("src_switch", flowPath.dataPath().srcPort().dpid().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800108 flowProp.setSrcSwitch(flowPath.dataPath().srcPort().dpid().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800109
110 flowPathEntity.setProperty("src_port", flowPath.dataPath().srcPort().port().value());
Toshio Koidec71b7122014-01-13 15:16:53 -0800111 flowProp.setSrcPort(flowPath.dataPath().srcPort().port().value());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800112
113 flowPathEntity.setProperty("dst_switch", flowPath.dataPath().dstPort().dpid().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800114 flowProp.setDstSwitch(flowPath.dataPath().dstPort().dpid().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800115
116 flowPathEntity.setProperty("dst_port", flowPath.dataPath().dstPort().port().value());
Toshio Koidec71b7122014-01-13 15:16:53 -0800117 flowProp.setDstPort(flowPath.dataPath().dstPort().port().value());
118
119 if (flowPath.flowEntryMatch().matchSrcMac()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800120 flowPathEntity.setProperty("matchSrcMac",flowPath.flowEntryMatch().srcMac().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800121 flowProp.setMatchSrcMac(flowPath.flowEntryMatch().srcMac().toString());
122 }
123 if (flowPath.flowEntryMatch().matchDstMac()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800124 flowPathEntity.setProperty("matchDstMac", flowPath.flowEntryMatch().dstMac().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800125 flowProp.setMatchDstMac(flowPath.flowEntryMatch().dstMac().toString());
126 }
127 if (flowPath.flowEntryMatch().matchEthernetFrameType()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800128 flowPathEntity.setProperty("matchEthernetFrameType", flowPath.flowEntryMatch().ethernetFrameType());
Toshio Koidec71b7122014-01-13 15:16:53 -0800129 flowProp.setMatchEthernetFrameType(flowPath.flowEntryMatch().ethernetFrameType());
130 }
131 if (flowPath.flowEntryMatch().matchVlanId()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800132 flowPathEntity.setProperty("matchVlanId", flowPath.flowEntryMatch().vlanId());
Toshio Koidec71b7122014-01-13 15:16:53 -0800133 flowProp.setMatchVlanId(flowPath.flowEntryMatch().vlanId());
134 }
135 if (flowPath.flowEntryMatch().matchVlanPriority()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800136 flowPathEntity.setProperty("matchVlanPriority", flowPath.flowEntryMatch().vlanPriority());
Toshio Koidec71b7122014-01-13 15:16:53 -0800137 flowProp.setMatchVlanPriority(flowPath.flowEntryMatch().vlanPriority());
138 }
139 if (flowPath.flowEntryMatch().matchSrcIPv4Net()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800140 flowPathEntity.setProperty("matchSrcIPv4Net", flowPath.flowEntryMatch().srcIPv4Net().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800141 flowProp.setMatchSrcIPv4Net(flowPath.flowEntryMatch().srcIPv4Net().toString());
142 }
143 if (flowPath.flowEntryMatch().matchDstIPv4Net()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800144 flowPathEntity.setProperty("matchDstIPv4Net", flowPath.flowEntryMatch().dstIPv4Net().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800145 flowProp.setMatchDstIPv4Net(flowPath.flowEntryMatch().dstIPv4Net().toString());
146 }
147 if (flowPath.flowEntryMatch().matchIpProto()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800148 flowPathEntity.setProperty("matchIpProto", flowPath.flowEntryMatch().ipProto());
Toshio Koidec71b7122014-01-13 15:16:53 -0800149 flowProp.setMatchIpProto(flowPath.flowEntryMatch().ipProto());
150 }
151 if (flowPath.flowEntryMatch().matchIpToS()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800152 flowPathEntity.setProperty("matchIpToS", flowPath.flowEntryMatch().ipToS());
Toshio Koidec71b7122014-01-13 15:16:53 -0800153 flowProp.setMatchIpToS(flowPath.flowEntryMatch().ipToS());
154 }
155 if (flowPath.flowEntryMatch().matchSrcTcpUdpPort()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800156 flowPathEntity.setProperty("matchSrcTcpUdpPort", flowPath.flowEntryMatch().srcTcpUdpPort());
Toshio Koidec71b7122014-01-13 15:16:53 -0800157 flowProp.setMatchSrcTcpUdpPort(flowPath.flowEntryMatch().srcTcpUdpPort());
158 }
159 if (flowPath.flowEntryMatch().matchDstTcpUdpPort()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800160 flowPathEntity.setProperty("matchDstTcpUdpPort", flowPath.flowEntryMatch().dstTcpUdpPort());
Toshio Koidec71b7122014-01-13 15:16:53 -0800161 flowProp.setMatchDstTcpUdpPort(flowPath.flowEntryMatch().dstTcpUdpPort());
162 }
163 if (! flowPath.flowEntryActions().actions().isEmpty()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800164 flowPathEntity.setProperty("actions", flowPath.flowEntryActions().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800165 flowProp.setActions(flowPath.flowEntryActions().toString());
166 }
Toshio Koidec71b7122014-01-13 15:16:53 -0800167
Nick Karanatsios1e802382014-01-23 11:12:16 -0800168 flowProp.commitProperties(dbHandler, flowPathObj);
Toshio Koidec71b7122014-01-13 15:16:53 -0800169
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
Nick Karanatsios1e802382014-01-23 11:12:16 -0800178 IFlowEntry iFlowEntry;
Toshio Koidec71b7122014-01-13 15:16:53 -0800179 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 {
Nick Karanatsios1e802382014-01-23 11:12:16 -0800184 iFlowEntry = dbHandler.searchFlowEntry(flowEntry.flowEntryId()); // getVertices()
Toshio Koidec71b7122014-01-13 15:16:53 -0800185 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 -0800191 flowEntryEntity.operationBegin(DBOperationType.ADD.toString());
192 flowEntryEntity.setProperty("user_state", "FE_USER_ADD");
Toshio Koidec71b7122014-01-13 15:16:53 -0800193 flowEntryProp.setUserState("FE_USER_ADD");
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800194 flowEntryEntity.addEdge(flowPathObj, Direction.OUT, "flow");
Toshio Koidec71b7122014-01-13 15:16:53 -0800195 }
196 } catch (Exception e) {
Nick Karanatsios1e802382014-01-23 11:12:16 -0800197 // TODO do we really need to catch this exception.
Toshio Koidec71b7122014-01-13 15:16:53 -0800198 }
Toshio Koidec71b7122014-01-13 15:16:53 -0800199
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800200 flowEntryEntity.setProperty("flow_id", flowEntry.flowEntryId().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800201 // Set the Flow Entry key
Nick Karanatsios1e802382014-01-23 11:12:16 -0800202 flowEntryEntity.setProperty("flow_entry_id", flowEntry.flowEntryId().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800203
204 flowEntryEntity.setProperty("type", "flow_entry");
Toshio Koidec71b7122014-01-13 15:16:53 -0800205
206 // Set the Flow Entry Edges
207 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString()); // toshi memo: getVertices()
208
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800209 flowEntryEntity.setProperty("idle_timeout", flowEntry.idleTimeout());
Toshio Koidec71b7122014-01-13 15:16:53 -0800210
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800211 flowEntryEntity.setProperty("hard_timeout", flowEntry.hardTimeout());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800212
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800213 flowEntryEntity.setProperty("priority", flowEntry.priority());
214
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800215 flowEntryEntity.setProperty("switch_dpid", flowEntry.dpid().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800216
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800217 flowEntryEntity.addEdge(sw, Direction.OUT, "switch");
Toshio Koidec71b7122014-01-13 15:16:53 -0800218 if (flowEntry.flowEntryMatch().matchInPort()) {
219 IPortObject inport = dbHandler.searchPort(flowEntry.dpid().toString(), flowEntry.flowEntryMatch().inPort().value()); // toshi memo: getVertices()
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800220
221 flowEntryEntity.setProperty("matchInPort", flowEntry.flowEntryMatch().inPort().value());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800222 flowEntryEntity.addEdge(inport, Direction.OUT, "inport");
Toshio Koidec71b7122014-01-13 15:16:53 -0800223 }
224
225 // Set the Flow Entry attributes
226 if (flowEntry.flowEntryMatch().matchSrcMac()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800227 flowEntryEntity.setProperty("matchSrcMac", flowEntry.flowEntryMatch().srcMac().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800228 }
229 if (flowEntry.flowEntryMatch().matchDstMac()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800230 flowEntryEntity.setProperty("matchDstMac", flowEntry.flowEntryMatch().dstMac().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800231 }
232 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800233 flowEntryEntity.setProperty("matchEthernetFrameType", flowEntry.flowEntryMatch().ethernetFrameType());
Toshio Koidec71b7122014-01-13 15:16:53 -0800234 }
235 if (flowEntry.flowEntryMatch().matchVlanId()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800236 flowEntryEntity.setProperty("matchVlanId", flowEntry.flowEntryMatch().vlanId());
Toshio Koidec71b7122014-01-13 15:16:53 -0800237 }
238 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800239 flowEntryEntity.setProperty("matchVlanPriority", flowEntry.flowEntryMatch().vlanPriority());
Toshio Koidec71b7122014-01-13 15:16:53 -0800240 }
241 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800242 flowEntryEntity.setProperty("matchSrcIPv4Net", flowEntry.flowEntryMatch().srcIPv4Net().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800243 }
244 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800245 flowEntryEntity.setProperty("matchDstIPv4Net", flowEntry.flowEntryMatch().dstIPv4Net().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800246 }
247 if (flowEntry.flowEntryMatch().matchIpProto()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800248 flowEntryEntity.setProperty("matchIpProto", flowEntry.flowEntryMatch().ipProto());
Toshio Koidec71b7122014-01-13 15:16:53 -0800249 }
250 if (flowEntry.flowEntryMatch().matchIpToS()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800251 flowEntryEntity.setProperty("matchIpToS", flowEntry.flowEntryMatch().ipToS());
Toshio Koidec71b7122014-01-13 15:16:53 -0800252 }
253 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800254 flowEntryEntity.setProperty("matchSrcTcpUdpPort", flowEntry.flowEntryMatch().srcTcpUdpPort());
Toshio Koidec71b7122014-01-13 15:16:53 -0800255 }
256 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800257 flowEntryEntity.setProperty("matchDstTcpUdpPort", flowEntry.flowEntryMatch().dstTcpUdpPort());
Toshio Koidec71b7122014-01-13 15:16:53 -0800258 }
259
260 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
261 if (fa.actionOutput() != null) {
262 IPortObject outport = dbHandler.searchPort(flowEntry.dpid().toString(), fa.actionOutput().port().value()); // toshi memo: getVertices()
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800263 flowEntryEntity.setProperty("actionOutputPort", fa.actionOutput().port().value());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800264 flowEntryEntity.addEdge(outport, Direction.OUT, "outport");
Toshio Koidec71b7122014-01-13 15:16:53 -0800265 }
266 }
267 if (! flowEntry.flowEntryActions().isEmpty()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800268 flowEntryEntity.setProperty("actions", flowEntry.flowEntryActions().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800269 }
270
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800271 flowEntryEntity.setProperty("switch_state", flowEntry.flowEntrySwitchState().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800272 if (updateFlowEntry) {
273 flowEntryEntity.operationEnd(DBOperationType.UPDATE.toString());
274 } else {
275 flowEntryEntity.operationEnd(DBOperationType.ADD.toString());
276 }
277 flowPathEntity.append(flowEntryEntity);
Toshio Koidec71b7122014-01-13 15:16:53 -0800278 }
279
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800280 if (flowPathUpdate) {
281 flowPathEntity.operationEnd(DBOperationType.UPDATE.toString());
282 } else {
283 flowPathEntity.operationEnd(DBOperationType.ADD.toString());
284 }
285 flowPathEntity.persist(dbHandler);
Toshio Koidec71b7122014-01-13 15:16:53 -0800286 return true;
287 }
288
289 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700290 * Add a flow.
291 *
292 * @param dbHandler the Graph Database handler to use.
293 * @param flowPath the Flow Path to install.
294 * @return true on success, otherwise false.
295 */
onlab-qa38805cd2013-12-06 20:08:54 -0800296 static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
Nick Karanatsios1e802382014-01-23 11:12:16 -0800297 PerfMon pm = PerfMon.getInstance();
298 pm.addflowpath_start();
299 boolean retValue = addFlowFast(dbHandler, flowPath);
300 pm.addflowpath_end();
301 return retValue;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700302 }
303
304 /**
305 * Add a flow entry to the Network MAP.
306 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700307 * @param dbHandler the Graph Database handler to use.
308 * @param flowObj the corresponding Flow Path object for the Flow Entry.
309 * @param flowEntry the Flow Entry to install.
310 * @return the added Flow Entry object on success, otherwise null.
311 */
onlab-qa38805cd2013-12-06 20:08:54 -0800312 static IFlowEntry addFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700313 IFlowPath flowObj,
314 FlowEntry flowEntry) {
315 // Flow edges
316 // HeadFE (TODO)
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800317 long startAddFlowEntry = 0;
318 long endAddFlowEntry = 0;
319
320 long endSearchFlowEntry = 0;
321
322 long startCreateNewFlowEntry = 0;
323 long endCreateNewFlowEntry = 0;
324
325 long startSetProperties = 0;
326 long endSetProperties = 0;
327 int numProperties = 0;
328
329 long startSearchSwitch = 0;
330 long endSearchSwitch = 0;
331
332 long startAddEdgeToSwitch =0;
333 long endAddEdgeToSwitch =0;
334
335 long startSearchInPort = 0;
336 long endSearchInPort = 0;
337
338 long startAddEdgeToInPort =0;
339 long endAddEdgeToInPort =0;
340
341 long startSearchOutPort = 0;
342 long endSearchOutPort = 0;
343
344 long startAddEdgeToOutPort =0;
345 long endAddEdgeToOutPort =0;
346
347 long startAddEdgeBetweenFlowPath = 0;
348 long endAddEdgeBetweenFlowPath = 0;
349
350 if (measureONOSFlowEntryTimeProp) {
351 startAddFlowEntry = System.nanoTime();
352 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700353
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700354 IFlowEntry flowEntryObj = null;
355 boolean found = false;
356 try {
Yuta HIGUCHIc27a6c92014-01-07 11:51:11 -0800357 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
358 if (measureONOSFlowEntryTimeProp) {
359 endSearchFlowEntry = System.nanoTime();
360 }
361 if (flowEntryObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700362 found = true;
363 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800364 if (measureONOSFlowEntryTimeProp) {
365 startCreateNewFlowEntry = System.nanoTime();
366 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700367 flowEntryObj = dbHandler.newFlowEntry();
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800368 if (measureONOSFlowEntryTimeProp) {
369 endCreateNewFlowEntry = System.nanoTime();
370 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700371 }
372 } catch (Exception e) {
373 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800374 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700375 return null;
376 }
377 if (flowEntryObj == null) {
378 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800379 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700380 return null;
381 }
382
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800383 if (measureONOSFlowEntryTimeProp) {
384 startSetProperties = System.nanoTime();
385 }
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800386
Toshio Koidec71b7122014-01-13 15:16:53 -0800387 FlowEntryProperty flowProp = new FlowEntryProperty();
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800388
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700389 //
390 // Set the Flow Entry key:
391 // - flowEntry.flowEntryId()
392 //
Toshio Koide3f233542014-01-07 14:19:09 -0800393 flowProp.setFlowEntryId(flowEntry.flowEntryId().toString());
394 flowProp.setType("flow_entry");
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800395 if (measureONOSFlowEntryTimeProp) {
396 numProperties += 2;
397 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700398
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800399 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700400 // Set the Flow Entry Edges and attributes:
401 // - Switch edge
402 // - InPort edge
403 // - OutPort edge
404 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800405 // - flowEntry.idleTimeout()
406 // - flowEntry.hardTimeout()
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800407 // - flowEntry.priority()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700408 // - flowEntry.dpid()
409 // - flowEntry.flowEntryUserState()
410 // - flowEntry.flowEntrySwitchState()
411 // - flowEntry.flowEntryErrorState()
412 // - flowEntry.matchInPort()
413 // - flowEntry.matchSrcMac()
414 // - flowEntry.matchDstMac()
415 // - flowEntry.matchEthernetFrameType()
416 // - flowEntry.matchVlanId()
417 // - flowEntry.matchVlanPriority()
418 // - flowEntry.matchSrcIPv4Net()
419 // - flowEntry.matchDstIPv4Net()
420 // - flowEntry.matchIpProto()
421 // - flowEntry.matchIpToS()
422 // - flowEntry.matchSrcTcpUdpPort()
423 // - flowEntry.matchDstTcpUdpPort()
424 // - flowEntry.actionOutputPort()
425 // - flowEntry.actions()
426 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800427 if (measureONOSFlowEntryTimeProp) {
428 startSearchSwitch = System.nanoTime();
429 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700430 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800431 if (measureONOSFlowEntryTimeProp) {
432 endSearchSwitch = System.nanoTime();
433 }
434
Toshio Koide3f233542014-01-07 14:19:09 -0800435 flowProp.setIdleTimeout(flowEntry.idleTimeout());
436 flowProp.setHardTimeout(flowEntry.hardTimeout());
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800437 flowProp.setPriority(flowEntry.priority());
Toshio Koide3f233542014-01-07 14:19:09 -0800438 flowProp.setSwitchDpid(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800439 if (measureONOSFlowEntryTimeProp) {
440 numProperties += 3;
441 }
442
443 if (measureONOSFlowEntryTimeProp) {
444 startAddEdgeToSwitch = System.nanoTime();
445 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700446 flowEntryObj.setSwitch(sw);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800447 if (measureONOSFlowEntryTimeProp) {
448 endAddEdgeToSwitch = System.nanoTime();
449 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700450 if (flowEntry.flowEntryMatch().matchInPort()) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800451 if (measureONOSFlowEntryTimeProp) {
452 startSearchInPort = System.nanoTime();
453 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700454 IPortObject inport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800455 dbHandler.searchPort(flowEntry.dpid().toString(),
456 flowEntry.flowEntryMatch().inPort().value());
457 if (measureONOSFlowEntryTimeProp) {
458 endSearchInPort = System.nanoTime();
459 }
460
Toshio Koide3f233542014-01-07 14:19:09 -0800461 flowProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800462 if (measureONOSFlowEntryTimeProp) {
463 ++numProperties;
464 }
465
466 if (measureONOSFlowEntryTimeProp) {
467 startAddEdgeToInPort = System.nanoTime();
468 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700469 flowEntryObj.setInPort(inport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800470 if (measureONOSFlowEntryTimeProp) {
471 endAddEdgeToInPort = System.nanoTime();
472 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700473 }
474 if (flowEntry.flowEntryMatch().matchSrcMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800475 flowProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800476 if (measureONOSFlowEntryTimeProp) {
477 ++numProperties;
478 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700479 }
480 if (flowEntry.flowEntryMatch().matchDstMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800481 flowProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800482 if (measureONOSFlowEntryTimeProp) {
483 ++numProperties;
484 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700485 }
486 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800487 flowProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800488 if (measureONOSFlowEntryTimeProp) {
489 ++numProperties;
490 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700491 }
492 if (flowEntry.flowEntryMatch().matchVlanId()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800493 flowProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800494 if (measureONOSFlowEntryTimeProp) {
495 ++numProperties;
496 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700497 }
498 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800499 flowProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800500 if (measureONOSFlowEntryTimeProp) {
501 ++numProperties;
502 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700503 }
504 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800505 flowProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800506 if (measureONOSFlowEntryTimeProp) {
507 ++numProperties;
508 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700509 }
510 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800511 flowProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800512 if (measureONOSFlowEntryTimeProp) {
513 ++numProperties;
514 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700515 }
516 if (flowEntry.flowEntryMatch().matchIpProto()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800517 flowProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800518 if (measureONOSFlowEntryTimeProp) {
519 ++numProperties;
520 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700521 }
522 if (flowEntry.flowEntryMatch().matchIpToS()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800523 flowProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800524 if (measureONOSFlowEntryTimeProp) {
525 ++numProperties;
526 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700527 }
528 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800529 flowProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800530 if (measureONOSFlowEntryTimeProp) {
531 ++numProperties;
532 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700533 }
534 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800535 flowProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800536 if (measureONOSFlowEntryTimeProp) {
537 ++numProperties;
538 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700539 }
540
541 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
542 if (fa.actionOutput() != null) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800543 if (measureONOSFlowEntryTimeProp) {
544 if ( startSearchOutPort != 0 ) log.error("Performance addFlowEntry(_,{},{}) -- Multiple output port action unexpected.", flowEntry.flowId(), flowEntry.flowEntryId());
545 startSearchOutPort = System.nanoTime();
546 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700547 IPortObject outport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800548 dbHandler.searchPort(flowEntry.dpid().toString(),
549 fa.actionOutput().port().value());
550 if (measureONOSFlowEntryTimeProp) {
551 endSearchOutPort = System.nanoTime();
552 }
553
Toshio Koide3f233542014-01-07 14:19:09 -0800554 flowProp.setActionOutputPort(fa.actionOutput().port().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800555 if (measureONOSFlowEntryTimeProp) {
556 ++numProperties;
557 }
558
559 if (measureONOSFlowEntryTimeProp) {
560 startAddEdgeToOutPort = System.nanoTime();
561 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700562 flowEntryObj.setOutPort(outport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800563 if (measureONOSFlowEntryTimeProp) {
564 endAddEdgeToOutPort = System.nanoTime();
565 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700566 }
567 }
568 if (! flowEntry.flowEntryActions().isEmpty()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800569 flowProp.setActions(flowEntry.flowEntryActions().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800570 if (measureONOSFlowEntryTimeProp) {
571 ++numProperties;
572 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700573 }
574
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800575 flowProp.setUserState(flowEntry.flowEntryUserState().toString());
Toshio Koide3f233542014-01-07 14:19:09 -0800576 flowProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800577 if (measureONOSFlowEntryTimeProp) {
578 numProperties += 2;
579 }
Toshio Koidec71b7122014-01-13 15:16:53 -0800580 flowProp.commitProperties(dbHandler, flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700581 //
582 // TODO: Take care of the FlowEntryErrorState.
583 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800584 if (measureONOSFlowEntryTimeProp) {
585 endSetProperties = System.nanoTime();
586 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700587
588 // Flow Entries edges:
589 // Flow
590 // NextFE (TODO)
591 if (! found) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800592 if (measureONOSFlowEntryTimeProp) {
593 startAddEdgeBetweenFlowPath = System.nanoTime();
594 }
Toshio Koidec71b7122014-01-13 15:16:53 -0800595 //flowObj.addFlowEntry(flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700596 flowEntryObj.setFlow(flowObj);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800597 if (measureONOSFlowEntryTimeProp) {
598 endAddEdgeBetweenFlowPath = System.nanoTime();
599 }
600 }
601 if (measureONOSFlowEntryTimeProp) {
602 endAddFlowEntry = System.nanoTime();
603
604 log.error("Performance addFlowEntry(_,{},{}) -- "
605 + "GrandTotal: {} "
606 + "SearchExistingFE: {} "
607 + "CreateNewFE: {} "
608 + "SetProp+Edge: {} #Props: {} "
609 + "SearchSwitch: {} "
610 + "AddEdgeToSwitch: {} "
611 + "SearchInPort: {} "
612 + "AddEdgeToInPort: {} "
613 + "SearchOutPort: {} "
614 + "AddEdgeToOutPort: {} "
615 + "AddEdgeBetweenFlowPath: {} "
616 , flowEntry.flowId(), flowEntry.flowEntryId()
617 , endAddFlowEntry - startAddFlowEntry
618 , endSearchFlowEntry - startAddFlowEntry
619 , endCreateNewFlowEntry - startCreateNewFlowEntry
620 , endSetProperties - startSetProperties, numProperties
621 , endSearchSwitch - startSearchSwitch
622 , endAddEdgeToSwitch - startAddEdgeToSwitch
623 , endSearchInPort - startSearchInPort
624 , endAddEdgeToInPort - startAddEdgeToInPort
625 , endSearchOutPort - startSearchOutPort
626 , endAddEdgeToOutPort - startAddEdgeToOutPort
627 , endAddEdgeBetweenFlowPath - startAddEdgeBetweenFlowPath
628 );
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700629 }
630
631 return flowEntryObj;
632 }
633
634 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700635 * Delete a flow entry from the Network MAP.
636 *
637 * @param dbHandler the Graph Database handler to use.
638 * @param flowObj the corresponding Flow Path object for the Flow Entry.
639 * @param flowEntry the Flow Entry to delete.
640 * @return true on success, otherwise false.
641 */
yoshitomob292c622013-11-23 14:35:58 -0800642 static boolean deleteFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700643 IFlowPath flowObj,
644 FlowEntry flowEntry) {
645 IFlowEntry flowEntryObj = null;
646 try {
647 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
648 } catch (Exception e) {
649 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800650 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700651 return false;
652 }
653 //
654 // TODO: Don't print an error for now, because multiple controller
655 // instances might be deleting the same flow entry.
656 //
657 /*
658 if (flowEntryObj == null) {
659 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800660 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700661 return false;
662 }
663 */
664 if (flowEntryObj == null)
665 return true;
666
667 flowObj.removeFlowEntry(flowEntryObj);
668 dbHandler.removeFlowEntry(flowEntryObj);
669 return true;
670 }
671
672 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700673 * Delete all previously added flows.
674 *
675 * @param dbHandler the Graph Database handler to use.
676 * @return true on success, otherwise false.
677 */
yoshitomob292c622013-11-23 14:35:58 -0800678 static boolean deleteAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700679 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
680 for (IFlowPath flowPathObj : allFlowPaths) {
681 if (flowPathObj == null)
682 continue;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700683
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800684 deleteIFlowPath(dbHandler, flowPathObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700685 }
Yuta HIGUCHI0cc22372014-01-13 14:54:00 -0800686 dbHandler.commit();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700687
688 return true;
689 }
690
691 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800692 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700693 *
694 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800695 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700696 * @return true on success, otherwise false.
697 */
yoshitomob292c622013-11-23 14:35:58 -0800698 static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700699 IFlowPath flowObj = null;
700 try {
701 flowObj = dbHandler.searchFlowPath(flowId);
702 } catch (Exception e) {
703 // TODO: handle exceptions
704 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800705 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700706 return false;
707 }
708 if (flowObj == null) {
709 dbHandler.commit();
710 return true; // OK: No such flow
711 }
712
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800713 deleteIFlowPath(dbHandler, flowObj);
Yuta HIGUCHI0cc22372014-01-13 14:54:00 -0800714 dbHandler.commit();
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800715 return true;
716 }
717
Yuta HIGUCHIeab1c8b2014-01-15 19:13:28 -0800718 /**
719 * Delete a previously added flow.
720 * @note You need to call commit after calling this method.
721 * @param dbHandler the Graph Database handler to use.
722 * @param flowObj IFlowPath object to delete.
723 */
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800724 private static void deleteIFlowPath(DBOperation dbHandler, IFlowPath flowObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700725 //
726 // Remove all Flow Entries
727 //
728 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
729 for (IFlowEntry flowEntryObj : flowEntries) {
730 flowObj.removeFlowEntry(flowEntryObj);
731 dbHandler.removeFlowEntry(flowEntryObj);
732 }
733 // Remove the Flow itself
734 dbHandler.removeFlowPath(flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700735 }
736
737 /**
738 * Get a previously added flow.
739 *
740 * @param dbHandler the Graph Database handler to use.
741 * @param flowId the Flow ID of the flow to get.
742 * @return the Flow Path if found, otherwise null.
743 */
yoshitomob292c622013-11-23 14:35:58 -0800744 static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700745 IFlowPath flowObj = null;
746 try {
747 flowObj = dbHandler.searchFlowPath(flowId);
748 } catch (Exception e) {
749 // TODO: handle exceptions
750 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800751 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700752 return null;
753 }
754 if (flowObj == null) {
755 dbHandler.commit();
756 return null; // Flow not found
757 }
758
759 //
760 // Extract the Flow state
761 //
762 FlowPath flowPath = extractFlowPath(flowObj);
763 dbHandler.commit();
764
765 return flowPath;
766 }
767
768 /**
Pavlin Radoslavov52119fa2014-01-09 13:37:52 -0800769 * Get a previously added flow entry.
770 *
771 * @param dbHandler the Graph Database handler to use.
772 * @param flowEntryId the Flow Entry ID of the flow entry to get.
773 * @return the Flow Entry if found, otherwise null.
774 */
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800775 static FlowEntry getFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov52119fa2014-01-09 13:37:52 -0800776 FlowEntryId flowEntryId) {
777 IFlowEntry flowEntryObj = null;
778 try {
779 flowEntryObj = dbHandler.searchFlowEntry(flowEntryId);
780 } catch (Exception e) {
781 // TODO: handle exceptions
782 dbHandler.rollback();
783 log.error(":getFlowEntry FlowEntryId:{} failed", flowEntryId);
784 return null;
785 }
786 if (flowEntryObj == null) {
787 dbHandler.commit();
788 return null; // Flow not found
789 }
790
791 //
792 // Extract the Flow Entry state
793 //
794 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
795 dbHandler.commit();
796
797 return flowEntry;
798 }
799
800 /**
Pavlin Radoslavov8252fee2014-01-07 17:24:29 -0800801 * Get the source switch DPID of a previously added flow.
802 *
803 * @param dbHandler the Graph Database handler to use.
804 * @param flowId the Flow ID of the flow to get.
805 * @return the source switch DPID if found, otherwise null.
806 */
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800807 static Dpid getFlowSourceDpid(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov8252fee2014-01-07 17:24:29 -0800808 IFlowPath flowObj = null;
809 try {
810 flowObj = dbHandler.searchFlowPath(flowId);
811 } catch (Exception e) {
812 // TODO: handle exceptions
813 dbHandler.rollback();
814 log.error(":getFlowSourceDpid FlowId:{} failed", flowId);
815 return null;
816 }
817 if (flowObj == null) {
818 dbHandler.commit();
819 return null; // Flow not found
820 }
821
822 //
823 // Extract the Flow Source DPID
824 //
825 String srcSwitchStr = flowObj.getSrcSwitch();
826 if (srcSwitchStr == null) {
827 // TODO: A work-around, becauuse of some bogus database objects
828 dbHandler.commit();
829 return null;
830 }
831
832 Dpid dpid = new Dpid(srcSwitchStr);
833
834 dbHandler.commit();
835
836 return dpid;
837 }
838
839 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700840 * Get all installed flows by all installers.
841 *
842 * @param dbHandler the Graph Database handler to use.
843 * @return the Flow Paths if found, otherwise null.
844 */
yoshitomob292c622013-11-23 14:35:58 -0800845 static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700846 Iterable<IFlowPath> flowPathsObj = null;
847 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
848
849 try {
850 flowPathsObj = dbHandler.getAllFlowPaths();
851 } catch (Exception e) {
852 // TODO: handle exceptions
853 dbHandler.rollback();
854 log.error(":getAllFlowPaths failed");
855 return flowPaths;
856 }
857 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
858 dbHandler.commit();
859 return flowPaths; // No Flows found
860 }
861
862 for (IFlowPath flowObj : flowPathsObj) {
863 //
864 // Extract the Flow state
865 //
866 FlowPath flowPath = extractFlowPath(flowObj);
867 if (flowPath != null)
868 flowPaths.add(flowPath);
869 }
870
871 dbHandler.commit();
872
873 return flowPaths;
874 }
875
876 /**
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -0800877 * Get all installed flows whose Source Switch is controlled by this
878 * instance.
879 *
880 * @param dbHandler the Graph Database handler to use.
881 * @param mySwitches the collection of the switches controlled by this
882 * instance.
883 * @return the Flow Paths if found, otherwise null.
884 */
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800885 static ArrayList<FlowPath> getAllMyFlows(DBOperation dbHandler,
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -0800886 Map<Long, IOFSwitch> mySwitches) {
887 Iterable<IFlowPath> flowPathsObj = null;
888 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
889
890 try {
891 flowPathsObj = dbHandler.getAllFlowPaths();
892 } catch (Exception e) {
893 // TODO: handle exceptions
894 dbHandler.rollback();
895 log.error(":getAllMyFlowPaths failed");
896 return flowPaths;
897 }
898 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
899 dbHandler.commit();
900 return flowPaths; // No Flows found
901 }
902
903 for (IFlowPath flowObj : flowPathsObj) {
904 //
905 // Extract the Source Switch DPID and ignore if the switch
906 // is not controlled by this instance.
907 //
908 String srcSwitchStr = flowObj.getSrcSwitch();
909 if (srcSwitchStr == null) {
910 // TODO: A work-around, becauuse of some bogus database objects
911 continue;
912 }
913 Dpid dpid = new Dpid(srcSwitchStr);
914 if (mySwitches.get(dpid.value()) == null)
915 continue;
916
917 //
918 // Extract the Flow state
919 //
920 FlowPath flowPath = extractFlowPath(flowObj);
921 if (flowPath != null)
922 flowPaths.add(flowPath);
923 }
924
925 dbHandler.commit();
926
927 return flowPaths;
928 }
929
930 /**
Pavlin Radoslavovf3f23bb2014-01-10 13:02:33 -0800931 * Get a subset of installed flows.
932 *
933 * @param dbHandler the Graph Database handler to use.
934 * @param flowIds the collection of Flow IDs to get.
935 * @return the Flow Paths if found, otherwise null.
936 */
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800937 static ArrayList<FlowPath> getFlows(DBOperation dbHandler,
Pavlin Radoslavovf3f23bb2014-01-10 13:02:33 -0800938 Collection<FlowId> flowIds) {
939 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
940
941 // TODO: This implementation should use threads
942 for (FlowId flowId : flowIds) {
943 FlowPath flowPath = getFlow(dbHandler, flowId);
944 if (flowPath != null)
945 flowPaths.add(flowPath);
946 }
947 // dbHandler.commit();
948
949 return flowPaths;
950 }
951
952 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700953 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
954 *
955 * @param flowObj the object to extract the Flow Path State from.
956 * @return the extracted Flow Path State.
957 */
Brian O'Connor2c38efe2014-01-10 15:41:57 -0800958 static FlowPath extractFlowPath(IFlowPath flowObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700959 //
960 // Extract the Flow state
961 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800962 log.info("extractFlowPath: start");
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -0800963 String flowIdStr;
964 String installerIdStr;
965 String flowPathType;
966 String flowPathUserState;
967 Long flowPathFlags;
968 Integer idleTimeout;
969 Integer hardTimeout;
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800970 Integer priority;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -0800971 String srcSwitchStr;
972 Short srcPortShort;
973 String dstSwitchStr;
974 Short dstPortShort;
975
976 if ( flowObj.asVertex() instanceof RamCloudVertex ) {
977 RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
978 Map<String,Object> propMap = v.getProperties();
979
980 flowIdStr = (String) propMap.get("flow_id");
981 installerIdStr = (String) propMap.get("installer_id");
982 flowPathType = (String) propMap.get("flow_path_type");
983 flowPathUserState = (String) propMap.get("user_state");
984 flowPathFlags = (Long)propMap.get("flow_path_flags");
985 idleTimeout = (Integer) propMap.get("idle_timeout");
986 hardTimeout = (Integer) propMap.get("hard_timeout");
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800987 priority = (Integer) propMap.get("priority");
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -0800988 srcSwitchStr = (String) propMap.get("src_switch");
989 srcPortShort = (Short)propMap.get("src_port");
990 dstSwitchStr = (String) propMap.get("dst_switch");
991 dstPortShort = (Short)propMap.get("dst_port");
992 } else {
993 flowIdStr = flowObj.getFlowId();
994 installerIdStr = flowObj.getInstallerId();
995 flowPathType = flowObj.getFlowPathType();
996 flowPathUserState = flowObj.getFlowPathUserState();
997 flowPathFlags = flowObj.getFlowPathFlags();
998 idleTimeout = flowObj.getIdleTimeout();
999 hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001000 priority = flowObj.getPriority();
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001001 srcSwitchStr = flowObj.getSrcSwitch();
1002 srcPortShort = flowObj.getSrcPort();
1003 dstSwitchStr = flowObj.getDstSwitch();
1004 dstPortShort = flowObj.getDstPort();
1005 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001006
1007 if ((flowIdStr == null) ||
1008 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -07001009 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -07001010 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001011 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001012 (idleTimeout == null) ||
1013 (hardTimeout == null) ||
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001014 (priority == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001015 (srcSwitchStr == null) ||
1016 (srcPortShort == null) ||
1017 (dstSwitchStr == null) ||
1018 (dstPortShort == null)) {
Toshio Koidea9b25142014-01-10 01:15:57 -08001019 // TODO: A work-around, because of some bogus database objects
1020 log.error("extractFlowPath: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001021 return null;
1022 }
1023
1024 FlowPath flowPath = new FlowPath();
1025 flowPath.setFlowId(new FlowId(flowIdStr));
1026 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -07001027 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -07001028 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001029 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001030 flowPath.setIdleTimeout(idleTimeout);
1031 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001032 flowPath.setPriority(priority);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001033 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
1034 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
1035 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
1036 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
1037 //
1038 // Extract the match conditions common for all Flow Entries
1039 //
1040 {
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001041 FlowEntryMatch match = extractMatch(flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001042
1043 flowPath.setFlowEntryMatch(match);
1044 }
1045 //
1046 // Extract the actions for the first Flow Entry
1047 //
1048 {
1049 String actionsStr = flowObj.getActions();
1050 if (actionsStr != null) {
1051 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
1052 flowPath.setFlowEntryActions(flowEntryActions);
1053 }
1054 }
1055
1056 //
1057 // Extract all Flow Entries
1058 //
1059 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
1060 for (IFlowEntry flowEntryObj : flowEntries) {
1061 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
1062 if (flowEntry == null)
1063 continue;
1064 flowPath.dataPath().flowEntries().add(flowEntry);
1065 }
1066
Toshio Koidea9b25142014-01-10 01:15:57 -08001067 log.info("extractFlowPath: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001068 return flowPath;
1069 }
1070
1071 /**
1072 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
1073 *
1074 * @param flowEntryObj the object to extract the Flow Entry State from.
1075 * @return the extracted Flow Entry State.
1076 */
Brian O'Connora8e49802013-10-30 20:49:59 -07001077 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Toshio Koidea9b25142014-01-10 01:15:57 -08001078 log.info("extractFlowEntry: start");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001079 IFlowPath flowObj = flowEntryObj.getFlow();
Toshio Koidea9b25142014-01-10 01:15:57 -08001080 if (flowObj == null) {
1081 log.error("extractFlowEntry: no flowPath exists");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001082 return null;
Toshio Koidea9b25142014-01-10 01:15:57 -08001083 }
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001084
1085 String flowIdStr = flowObj.getFlowId();
1086 //
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001087 String flowEntryIdStr;
1088 Integer idleTimeout;
1089 Integer hardTimeout;
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001090 Integer priority;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001091 String switchDpidStr;
1092 String userState;
1093 String switchState;
1094 if ( flowEntryObj.asVertex() instanceof RamCloudVertex ) {
1095 RamCloudVertex v = (RamCloudVertex)flowEntryObj.asVertex();
1096 Map<String,Object> propMap = v.getProperties();
1097
1098 flowEntryIdStr = (String) propMap.get("flow_entry_id");
1099 idleTimeout = (Integer) propMap.get("idle_timeout");
1100 hardTimeout = (Integer) propMap.get("hard_timeout");
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001101 priority = (Integer) propMap.get("priority");
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001102 switchDpidStr = (String) propMap.get("switch_dpid");
1103 userState = (String) propMap.get("user_state");
1104 switchState = (String) propMap.get("switch_state");
1105 } else {
1106 flowEntryIdStr = flowEntryObj.getFlowEntryId();
1107 idleTimeout = flowEntryObj.getIdleTimeout();
1108 hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001109 priority = flowEntryObj.getPriority();
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001110 switchDpidStr = flowEntryObj.getSwitchDpid();
1111 userState = flowEntryObj.getUserState();
1112 switchState = flowEntryObj.getSwitchState();
1113 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001114
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001115 if ((flowIdStr == null) ||
1116 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001117 (idleTimeout == null) ||
1118 (hardTimeout == null) ||
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001119 (priority == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001120 (switchDpidStr == null) ||
1121 (userState == null) ||
1122 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -07001123 // TODO: A work-around, because of some bogus database objects
Toshio Koidea9b25142014-01-10 01:15:57 -08001124 log.error("extractFlowEntry: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001125 return null;
1126 }
1127
1128 FlowEntry flowEntry = new FlowEntry();
1129 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001130 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001131 flowEntry.setDpid(new Dpid(switchDpidStr));
yoshia97632b2013-12-17 15:46:08 -08001132 flowEntry.setIdleTimeout(idleTimeout);
1133 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001134 flowEntry.setPriority(priority);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001135
1136 //
1137 // Extract the match conditions
1138 //
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001139 FlowEntryMatch match = extractMatch(flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001140 flowEntry.setFlowEntryMatch(match);
1141
1142 //
1143 // Extract the actions
1144 //
1145 FlowEntryActions actions = new FlowEntryActions();
1146 String actionsStr = flowEntryObj.getActions();
1147 if (actionsStr != null)
1148 actions = new FlowEntryActions(actionsStr);
1149 flowEntry.setFlowEntryActions(actions);
1150 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
1151 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
1152 //
1153 // TODO: Take care of FlowEntryErrorState.
1154 //
Toshio Koidea9b25142014-01-10 01:15:57 -08001155 log.info("extractFlowEntry: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001156 return flowEntry;
1157 }
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001158
1159 /**
1160 * Extract FlowEntryMatch from IFlowPath or IFlowEntry
1161 * @param flowObj : either IFlowPath or IFlowEntry
1162 * @return extracted Match info
1163 */
1164 private static FlowEntryMatch extractMatch(IBaseObject flowObj) {
1165 FlowEntryMatch match = new FlowEntryMatch();
1166
1167 Short matchInPort = null; // Only for IFlowEntry
1168 String matchSrcMac = null;
1169 String matchDstMac = null;
1170 Short matchEthernetFrameType = null;
1171 Short matchVlanId = null;
1172 Byte matchVlanPriority = null;
1173 String matchSrcIPv4Net = null;
1174 String matchDstIPv4Net = null;
1175 Byte matchIpProto = null;
1176 Byte matchIpToS = null;
1177 Short matchSrcTcpUdpPort = null;
1178 Short matchDstTcpUdpPort = null;
1179
1180 if ( flowObj.asVertex() instanceof RamCloudVertex ) {
1181 RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
1182 Map<String,Object> propMap = v.getProperties();
1183 matchInPort = (Short) propMap.get("matchInPort");
1184 matchSrcMac = (String) propMap.get("matchSrcMac");
1185 matchDstMac = (String) propMap.get("matchDstMac");
1186 matchEthernetFrameType = (Short) propMap.get("matchEthernetFrameType");
1187 matchVlanId = (Short) propMap.get("matchVlanId");
1188 matchVlanPriority = (Byte) propMap.get("matchVlanPriority");
1189 matchSrcIPv4Net = (String) propMap.get("matchSrcIPv4Net");
1190 matchDstIPv4Net = (String) propMap.get("matchDstIPv4Net");
1191 matchIpProto = (Byte) propMap.get("matchIpProto");
1192 matchIpToS = (Byte) propMap.get("matchIpToS");
1193 matchSrcTcpUdpPort = (Short) propMap.get("matchSrcTcpUdpPort");
1194 matchDstTcpUdpPort = (Short) propMap.get("matchDstTcpUdpPort");
1195 } else {
1196 if (flowObj instanceof IFlowEntry ){
1197 IFlowEntry flowEntry = (IFlowEntry) flowObj;
1198 matchInPort = flowEntry.getMatchInPort();
1199 matchSrcMac = flowEntry.getMatchSrcMac();
1200 matchDstMac = flowEntry.getMatchDstMac();
1201 matchEthernetFrameType = flowEntry.getMatchEthernetFrameType();
1202 matchVlanId = flowEntry.getMatchVlanId();
1203 matchVlanPriority = flowEntry.getMatchVlanPriority();
1204 matchSrcIPv4Net = flowEntry.getMatchSrcIPv4Net();
1205 matchDstIPv4Net = flowEntry.getMatchDstIPv4Net();
1206 matchIpProto = flowEntry.getMatchIpProto();
1207 matchIpToS = flowEntry.getMatchIpToS();
1208 matchSrcTcpUdpPort = flowEntry.getMatchSrcTcpUdpPort();
1209 matchDstTcpUdpPort = flowEntry.getMatchDstTcpUdpPort();
1210 } else if(flowObj instanceof IFlowPath) {
1211 IFlowPath flowPath = (IFlowPath) flowObj;
1212 matchSrcMac = flowPath.getMatchSrcMac();
1213 matchDstMac = flowPath.getMatchDstMac();
1214 matchEthernetFrameType = flowPath.getMatchEthernetFrameType();
1215 matchVlanId = flowPath.getMatchVlanId();
1216 matchVlanPriority = flowPath.getMatchVlanPriority();
1217 matchSrcIPv4Net = flowPath.getMatchSrcIPv4Net();
1218 matchDstIPv4Net = flowPath.getMatchDstIPv4Net();
1219 matchIpProto = flowPath.getMatchIpProto();
1220 matchIpToS = flowPath.getMatchIpToS();
1221 matchSrcTcpUdpPort = flowPath.getMatchSrcTcpUdpPort();
1222 matchDstTcpUdpPort = flowPath.getMatchDstTcpUdpPort();
1223 }
1224 }
1225
1226 if (matchInPort != null)
1227 match.enableInPort(new Port(matchInPort));
1228 if (matchSrcMac != null)
1229 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
1230 if (matchDstMac != null)
1231 match.enableDstMac(MACAddress.valueOf(matchDstMac));
1232 if (matchEthernetFrameType != null)
1233 match.enableEthernetFrameType(matchEthernetFrameType);
1234 if (matchVlanId != null)
1235 match.enableVlanId(matchVlanId);
1236 if (matchVlanPriority != null)
1237 match.enableVlanPriority(matchVlanPriority);
1238 if (matchSrcIPv4Net != null)
1239 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
1240 if (matchDstIPv4Net != null)
1241 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
1242 if (matchIpProto != null)
1243 match.enableIpProto(matchIpProto);
1244 if (matchIpToS != null)
1245 match.enableIpToS(matchIpToS);
1246 if (matchSrcTcpUdpPort != null)
1247 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
1248 if (matchDstTcpUdpPort != null)
1249 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
1250 return match;
1251 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001252}