blob: ec3064e52cda414f53d7f8f22729a472dd3ba897 [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 }
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800167 flowPathEntity.setProperty("data_path_summary", flowPath.dataPath().dataPathSummary());
Toshio Koidec71b7122014-01-13 15:16:53 -0800168 flowProp.setDataPathSummary(flowPath.dataPath().dataPathSummary());
169
Nick Karanatsios1e802382014-01-23 11:12:16 -0800170 flowProp.commitProperties(dbHandler, flowPathObj);
Toshio Koidec71b7122014-01-13 15:16:53 -0800171
172 //
173 // Flow Entries:
174 // flowPath.dataPath().flowEntries()
175 //
176 for (FlowEntry flowEntry : flowPath.dataPath().flowEntries()) {
177 if (flowEntry.flowEntryUserState() == FlowEntryUserState.FE_USER_DELETE)
178 continue; // Skip: all Flow Entries were deleted earlier
179
Nick Karanatsios1e802382014-01-23 11:12:16 -0800180 IFlowEntry iFlowEntry;
Toshio Koidec71b7122014-01-13 15:16:53 -0800181 FlowEntryProperty flowEntryProp = new FlowEntryProperty();
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800182 FlowEntity flowEntryEntity = new FlowEntity();
183 boolean updateFlowEntry = false;
Toshio Koidec71b7122014-01-13 15:16:53 -0800184
185 try {
Nick Karanatsios1e802382014-01-23 11:12:16 -0800186 iFlowEntry = dbHandler.searchFlowEntry(flowEntry.flowEntryId()); // getVertices()
Toshio Koidec71b7122014-01-13 15:16:53 -0800187 if (iFlowEntry != null) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800188 updateFlowEntry = true;
189 flowEntryEntity.operationBegin(DBOperationType.UPDATE.toString());
190 flowEntryEntity.setProperty("user_state", "FE_USER_MODIFY");
Toshio Koidec71b7122014-01-13 15:16:53 -0800191 flowEntryProp.setUserState("FE_USER_MODIFY");
192 } else {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800193 flowEntryEntity.operationBegin(DBOperationType.ADD.toString());
194 flowEntryEntity.setProperty("user_state", "FE_USER_ADD");
Toshio Koidec71b7122014-01-13 15:16:53 -0800195 flowEntryProp.setUserState("FE_USER_ADD");
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800196 flowEntryEntity.addEdge(flowPathObj, Direction.OUT, "flow");
Toshio Koidec71b7122014-01-13 15:16:53 -0800197 }
198 } catch (Exception e) {
Nick Karanatsios1e802382014-01-23 11:12:16 -0800199 // TODO do we really need to catch this exception.
Toshio Koidec71b7122014-01-13 15:16:53 -0800200 }
Toshio Koidec71b7122014-01-13 15:16:53 -0800201
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800202 flowEntryEntity.setProperty("flow_id", flowEntry.flowEntryId().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800203 // Set the Flow Entry key
Nick Karanatsios1e802382014-01-23 11:12:16 -0800204 flowEntryEntity.setProperty("flow_entry_id", flowEntry.flowEntryId().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800205
206 flowEntryEntity.setProperty("type", "flow_entry");
Toshio Koidec71b7122014-01-13 15:16:53 -0800207
208 // Set the Flow Entry Edges
209 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString()); // toshi memo: getVertices()
210
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800211 flowEntryEntity.setProperty("idle_timeout", flowEntry.idleTimeout());
Toshio Koidec71b7122014-01-13 15:16:53 -0800212
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800213 flowEntryEntity.setProperty("hard_timeout", flowEntry.hardTimeout());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800214
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800215 flowEntryEntity.setProperty("priority", flowEntry.priority());
216
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800217 flowEntryEntity.setProperty("switch_dpid", flowEntry.dpid().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800218
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800219 flowEntryEntity.addEdge(sw, Direction.OUT, "switch");
Toshio Koidec71b7122014-01-13 15:16:53 -0800220 if (flowEntry.flowEntryMatch().matchInPort()) {
221 IPortObject inport = dbHandler.searchPort(flowEntry.dpid().toString(), flowEntry.flowEntryMatch().inPort().value()); // toshi memo: getVertices()
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800222
223 flowEntryEntity.setProperty("matchInPort", flowEntry.flowEntryMatch().inPort().value());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800224 flowEntryEntity.addEdge(inport, Direction.OUT, "inport");
Toshio Koidec71b7122014-01-13 15:16:53 -0800225 }
226
227 // Set the Flow Entry attributes
228 if (flowEntry.flowEntryMatch().matchSrcMac()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800229 flowEntryEntity.setProperty("matchSrcMac", flowEntry.flowEntryMatch().srcMac().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800230 }
231 if (flowEntry.flowEntryMatch().matchDstMac()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800232 flowEntryEntity.setProperty("matchDstMac", flowEntry.flowEntryMatch().dstMac().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800233 }
234 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800235 flowEntryEntity.setProperty("matchEthernetFrameType", flowEntry.flowEntryMatch().ethernetFrameType());
Toshio Koidec71b7122014-01-13 15:16:53 -0800236 }
237 if (flowEntry.flowEntryMatch().matchVlanId()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800238 flowEntryEntity.setProperty("matchVlanId", flowEntry.flowEntryMatch().vlanId());
Toshio Koidec71b7122014-01-13 15:16:53 -0800239 }
240 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800241 flowEntryEntity.setProperty("matchVlanPriority", flowEntry.flowEntryMatch().vlanPriority());
Toshio Koidec71b7122014-01-13 15:16:53 -0800242 }
243 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800244 flowEntryEntity.setProperty("matchSrcIPv4Net", flowEntry.flowEntryMatch().srcIPv4Net().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800245 }
246 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800247 flowEntryEntity.setProperty("matchDstIPv4Net", flowEntry.flowEntryMatch().dstIPv4Net().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800248 }
249 if (flowEntry.flowEntryMatch().matchIpProto()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800250 flowEntryEntity.setProperty("matchIpProto", flowEntry.flowEntryMatch().ipProto());
Toshio Koidec71b7122014-01-13 15:16:53 -0800251 }
252 if (flowEntry.flowEntryMatch().matchIpToS()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800253 flowEntryEntity.setProperty("matchIpToS", flowEntry.flowEntryMatch().ipToS());
Toshio Koidec71b7122014-01-13 15:16:53 -0800254 }
255 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800256 flowEntryEntity.setProperty("matchSrcTcpUdpPort", flowEntry.flowEntryMatch().srcTcpUdpPort());
Toshio Koidec71b7122014-01-13 15:16:53 -0800257 }
258 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800259 flowEntryEntity.setProperty("matchDstTcpUdpPort", flowEntry.flowEntryMatch().dstTcpUdpPort());
Toshio Koidec71b7122014-01-13 15:16:53 -0800260 }
261
262 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
263 if (fa.actionOutput() != null) {
264 IPortObject outport = dbHandler.searchPort(flowEntry.dpid().toString(), fa.actionOutput().port().value()); // toshi memo: getVertices()
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800265 flowEntryEntity.setProperty("actionOutputPort", fa.actionOutput().port().value());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800266 flowEntryEntity.addEdge(outport, Direction.OUT, "outport");
Toshio Koidec71b7122014-01-13 15:16:53 -0800267 }
268 }
269 if (! flowEntry.flowEntryActions().isEmpty()) {
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800270 flowEntryEntity.setProperty("actions", flowEntry.flowEntryActions().toString());
Toshio Koidec71b7122014-01-13 15:16:53 -0800271 }
272
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800273 flowEntryEntity.setProperty("switch_state", flowEntry.flowEntrySwitchState().toString());
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800274 if (updateFlowEntry) {
275 flowEntryEntity.operationEnd(DBOperationType.UPDATE.toString());
276 } else {
277 flowEntryEntity.operationEnd(DBOperationType.ADD.toString());
278 }
279 flowPathEntity.append(flowEntryEntity);
Toshio Koidec71b7122014-01-13 15:16:53 -0800280 }
281
Nick Karanatsios758df8d2014-01-14 22:16:32 -0800282 if (flowPathUpdate) {
283 flowPathEntity.operationEnd(DBOperationType.UPDATE.toString());
284 } else {
285 flowPathEntity.operationEnd(DBOperationType.ADD.toString());
286 }
287 flowPathEntity.persist(dbHandler);
Toshio Koidec71b7122014-01-13 15:16:53 -0800288 return true;
289 }
290
291 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700292 * Add a flow.
293 *
294 * @param dbHandler the Graph Database handler to use.
295 * @param flowPath the Flow Path to install.
296 * @return true on success, otherwise false.
297 */
onlab-qa38805cd2013-12-06 20:08:54 -0800298 static boolean addFlow(DBOperation dbHandler, FlowPath flowPath) {
Nick Karanatsios1e802382014-01-23 11:12:16 -0800299 PerfMon pm = PerfMon.getInstance();
300 pm.addflowpath_start();
301 boolean retValue = addFlowFast(dbHandler, flowPath);
302 pm.addflowpath_end();
303 return retValue;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700304 }
305
306 /**
307 * Add a flow entry to the Network MAP.
308 *
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700309 * @param dbHandler the Graph Database handler to use.
310 * @param flowObj the corresponding Flow Path object for the Flow Entry.
311 * @param flowEntry the Flow Entry to install.
312 * @return the added Flow Entry object on success, otherwise null.
313 */
onlab-qa38805cd2013-12-06 20:08:54 -0800314 static IFlowEntry addFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700315 IFlowPath flowObj,
316 FlowEntry flowEntry) {
317 // Flow edges
318 // HeadFE (TODO)
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800319 long startAddFlowEntry = 0;
320 long endAddFlowEntry = 0;
321
322 long endSearchFlowEntry = 0;
323
324 long startCreateNewFlowEntry = 0;
325 long endCreateNewFlowEntry = 0;
326
327 long startSetProperties = 0;
328 long endSetProperties = 0;
329 int numProperties = 0;
330
331 long startSearchSwitch = 0;
332 long endSearchSwitch = 0;
333
334 long startAddEdgeToSwitch =0;
335 long endAddEdgeToSwitch =0;
336
337 long startSearchInPort = 0;
338 long endSearchInPort = 0;
339
340 long startAddEdgeToInPort =0;
341 long endAddEdgeToInPort =0;
342
343 long startSearchOutPort = 0;
344 long endSearchOutPort = 0;
345
346 long startAddEdgeToOutPort =0;
347 long endAddEdgeToOutPort =0;
348
349 long startAddEdgeBetweenFlowPath = 0;
350 long endAddEdgeBetweenFlowPath = 0;
351
352 if (measureONOSFlowEntryTimeProp) {
353 startAddFlowEntry = System.nanoTime();
354 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700355
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700356 IFlowEntry flowEntryObj = null;
357 boolean found = false;
358 try {
Yuta HIGUCHIc27a6c92014-01-07 11:51:11 -0800359 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
360 if (measureONOSFlowEntryTimeProp) {
361 endSearchFlowEntry = System.nanoTime();
362 }
363 if (flowEntryObj != null) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700364 found = true;
365 } else {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800366 if (measureONOSFlowEntryTimeProp) {
367 startCreateNewFlowEntry = System.nanoTime();
368 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700369 flowEntryObj = dbHandler.newFlowEntry();
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800370 if (measureONOSFlowEntryTimeProp) {
371 endCreateNewFlowEntry = System.nanoTime();
372 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700373 }
374 } catch (Exception e) {
375 log.error(":addFlow FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800376 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700377 return null;
378 }
379 if (flowEntryObj == null) {
380 log.error(":addFlow FlowEntryId:{} failed: FlowEntry object not created",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800381 flowEntry.flowEntryId());
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700382 return null;
383 }
384
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800385 if (measureONOSFlowEntryTimeProp) {
386 startSetProperties = System.nanoTime();
387 }
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800388
Toshio Koidec71b7122014-01-13 15:16:53 -0800389 FlowEntryProperty flowProp = new FlowEntryProperty();
Yuta HIGUCHI8685f9c2014-01-07 15:53:28 -0800390
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700391 //
392 // Set the Flow Entry key:
393 // - flowEntry.flowEntryId()
394 //
Toshio Koide3f233542014-01-07 14:19:09 -0800395 flowProp.setFlowEntryId(flowEntry.flowEntryId().toString());
396 flowProp.setType("flow_entry");
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800397 if (measureONOSFlowEntryTimeProp) {
398 numProperties += 2;
399 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700400
Yuta HIGUCHI37c55472014-01-03 11:42:27 -0800401 //
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700402 // Set the Flow Entry Edges and attributes:
403 // - Switch edge
404 // - InPort edge
405 // - OutPort edge
406 //
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -0800407 // - flowEntry.idleTimeout()
408 // - flowEntry.hardTimeout()
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800409 // - flowEntry.priority()
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700410 // - flowEntry.dpid()
411 // - flowEntry.flowEntryUserState()
412 // - flowEntry.flowEntrySwitchState()
413 // - flowEntry.flowEntryErrorState()
414 // - flowEntry.matchInPort()
415 // - flowEntry.matchSrcMac()
416 // - flowEntry.matchDstMac()
417 // - flowEntry.matchEthernetFrameType()
418 // - flowEntry.matchVlanId()
419 // - flowEntry.matchVlanPriority()
420 // - flowEntry.matchSrcIPv4Net()
421 // - flowEntry.matchDstIPv4Net()
422 // - flowEntry.matchIpProto()
423 // - flowEntry.matchIpToS()
424 // - flowEntry.matchSrcTcpUdpPort()
425 // - flowEntry.matchDstTcpUdpPort()
426 // - flowEntry.actionOutputPort()
427 // - flowEntry.actions()
428 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800429 if (measureONOSFlowEntryTimeProp) {
430 startSearchSwitch = System.nanoTime();
431 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700432 ISwitchObject sw = dbHandler.searchSwitch(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800433 if (measureONOSFlowEntryTimeProp) {
434 endSearchSwitch = System.nanoTime();
435 }
436
Toshio Koide3f233542014-01-07 14:19:09 -0800437 flowProp.setIdleTimeout(flowEntry.idleTimeout());
438 flowProp.setHardTimeout(flowEntry.hardTimeout());
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800439 flowProp.setPriority(flowEntry.priority());
Toshio Koide3f233542014-01-07 14:19:09 -0800440 flowProp.setSwitchDpid(flowEntry.dpid().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800441 if (measureONOSFlowEntryTimeProp) {
442 numProperties += 3;
443 }
444
445 if (measureONOSFlowEntryTimeProp) {
446 startAddEdgeToSwitch = System.nanoTime();
447 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700448 flowEntryObj.setSwitch(sw);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800449 if (measureONOSFlowEntryTimeProp) {
450 endAddEdgeToSwitch = System.nanoTime();
451 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700452 if (flowEntry.flowEntryMatch().matchInPort()) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800453 if (measureONOSFlowEntryTimeProp) {
454 startSearchInPort = System.nanoTime();
455 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700456 IPortObject inport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800457 dbHandler.searchPort(flowEntry.dpid().toString(),
458 flowEntry.flowEntryMatch().inPort().value());
459 if (measureONOSFlowEntryTimeProp) {
460 endSearchInPort = System.nanoTime();
461 }
462
Toshio Koide3f233542014-01-07 14:19:09 -0800463 flowProp.setMatchInPort(flowEntry.flowEntryMatch().inPort().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800464 if (measureONOSFlowEntryTimeProp) {
465 ++numProperties;
466 }
467
468 if (measureONOSFlowEntryTimeProp) {
469 startAddEdgeToInPort = System.nanoTime();
470 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700471 flowEntryObj.setInPort(inport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800472 if (measureONOSFlowEntryTimeProp) {
473 endAddEdgeToInPort = System.nanoTime();
474 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700475 }
476 if (flowEntry.flowEntryMatch().matchSrcMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800477 flowProp.setMatchSrcMac(flowEntry.flowEntryMatch().srcMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800478 if (measureONOSFlowEntryTimeProp) {
479 ++numProperties;
480 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700481 }
482 if (flowEntry.flowEntryMatch().matchDstMac()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800483 flowProp.setMatchDstMac(flowEntry.flowEntryMatch().dstMac().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800484 if (measureONOSFlowEntryTimeProp) {
485 ++numProperties;
486 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700487 }
488 if (flowEntry.flowEntryMatch().matchEthernetFrameType()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800489 flowProp.setMatchEthernetFrameType(flowEntry.flowEntryMatch().ethernetFrameType());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800490 if (measureONOSFlowEntryTimeProp) {
491 ++numProperties;
492 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700493 }
494 if (flowEntry.flowEntryMatch().matchVlanId()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800495 flowProp.setMatchVlanId(flowEntry.flowEntryMatch().vlanId());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800496 if (measureONOSFlowEntryTimeProp) {
497 ++numProperties;
498 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700499 }
500 if (flowEntry.flowEntryMatch().matchVlanPriority()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800501 flowProp.setMatchVlanPriority(flowEntry.flowEntryMatch().vlanPriority());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800502 if (measureONOSFlowEntryTimeProp) {
503 ++numProperties;
504 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700505 }
506 if (flowEntry.flowEntryMatch().matchSrcIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800507 flowProp.setMatchSrcIPv4Net(flowEntry.flowEntryMatch().srcIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800508 if (measureONOSFlowEntryTimeProp) {
509 ++numProperties;
510 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700511 }
512 if (flowEntry.flowEntryMatch().matchDstIPv4Net()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800513 flowProp.setMatchDstIPv4Net(flowEntry.flowEntryMatch().dstIPv4Net().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800514 if (measureONOSFlowEntryTimeProp) {
515 ++numProperties;
516 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700517 }
518 if (flowEntry.flowEntryMatch().matchIpProto()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800519 flowProp.setMatchIpProto(flowEntry.flowEntryMatch().ipProto());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800520 if (measureONOSFlowEntryTimeProp) {
521 ++numProperties;
522 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700523 }
524 if (flowEntry.flowEntryMatch().matchIpToS()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800525 flowProp.setMatchIpToS(flowEntry.flowEntryMatch().ipToS());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800526 if (measureONOSFlowEntryTimeProp) {
527 ++numProperties;
528 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700529 }
530 if (flowEntry.flowEntryMatch().matchSrcTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800531 flowProp.setMatchSrcTcpUdpPort(flowEntry.flowEntryMatch().srcTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800532 if (measureONOSFlowEntryTimeProp) {
533 ++numProperties;
534 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700535 }
536 if (flowEntry.flowEntryMatch().matchDstTcpUdpPort()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800537 flowProp.setMatchDstTcpUdpPort(flowEntry.flowEntryMatch().dstTcpUdpPort());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800538 if (measureONOSFlowEntryTimeProp) {
539 ++numProperties;
540 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700541 }
542
543 for (FlowEntryAction fa : flowEntry.flowEntryActions().actions()) {
544 if (fa.actionOutput() != null) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800545 if (measureONOSFlowEntryTimeProp) {
546 if ( startSearchOutPort != 0 ) log.error("Performance addFlowEntry(_,{},{}) -- Multiple output port action unexpected.", flowEntry.flowId(), flowEntry.flowEntryId());
547 startSearchOutPort = System.nanoTime();
548 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700549 IPortObject outport =
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800550 dbHandler.searchPort(flowEntry.dpid().toString(),
551 fa.actionOutput().port().value());
552 if (measureONOSFlowEntryTimeProp) {
553 endSearchOutPort = System.nanoTime();
554 }
555
Toshio Koide3f233542014-01-07 14:19:09 -0800556 flowProp.setActionOutputPort(fa.actionOutput().port().value());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800557 if (measureONOSFlowEntryTimeProp) {
558 ++numProperties;
559 }
560
561 if (measureONOSFlowEntryTimeProp) {
562 startAddEdgeToOutPort = System.nanoTime();
563 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700564 flowEntryObj.setOutPort(outport);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800565 if (measureONOSFlowEntryTimeProp) {
566 endAddEdgeToOutPort = System.nanoTime();
567 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700568 }
569 }
570 if (! flowEntry.flowEntryActions().isEmpty()) {
Toshio Koide3f233542014-01-07 14:19:09 -0800571 flowProp.setActions(flowEntry.flowEntryActions().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800572 if (measureONOSFlowEntryTimeProp) {
573 ++numProperties;
574 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700575 }
576
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800577 flowProp.setUserState(flowEntry.flowEntryUserState().toString());
Toshio Koide3f233542014-01-07 14:19:09 -0800578 flowProp.setSwitchState(flowEntry.flowEntrySwitchState().toString());
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800579 if (measureONOSFlowEntryTimeProp) {
580 numProperties += 2;
581 }
Toshio Koidec71b7122014-01-13 15:16:53 -0800582 flowProp.commitProperties(dbHandler, flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700583 //
584 // TODO: Take care of the FlowEntryErrorState.
585 //
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800586 if (measureONOSFlowEntryTimeProp) {
587 endSetProperties = System.nanoTime();
588 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700589
590 // Flow Entries edges:
591 // Flow
592 // NextFE (TODO)
593 if (! found) {
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800594 if (measureONOSFlowEntryTimeProp) {
595 startAddEdgeBetweenFlowPath = System.nanoTime();
596 }
Toshio Koidec71b7122014-01-13 15:16:53 -0800597 //flowObj.addFlowEntry(flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700598 flowEntryObj.setFlow(flowObj);
Yuta HIGUCHIf9ce1c12014-01-04 23:21:58 -0800599 if (measureONOSFlowEntryTimeProp) {
600 endAddEdgeBetweenFlowPath = System.nanoTime();
601 }
602 }
603 if (measureONOSFlowEntryTimeProp) {
604 endAddFlowEntry = System.nanoTime();
605
606 log.error("Performance addFlowEntry(_,{},{}) -- "
607 + "GrandTotal: {} "
608 + "SearchExistingFE: {} "
609 + "CreateNewFE: {} "
610 + "SetProp+Edge: {} #Props: {} "
611 + "SearchSwitch: {} "
612 + "AddEdgeToSwitch: {} "
613 + "SearchInPort: {} "
614 + "AddEdgeToInPort: {} "
615 + "SearchOutPort: {} "
616 + "AddEdgeToOutPort: {} "
617 + "AddEdgeBetweenFlowPath: {} "
618 , flowEntry.flowId(), flowEntry.flowEntryId()
619 , endAddFlowEntry - startAddFlowEntry
620 , endSearchFlowEntry - startAddFlowEntry
621 , endCreateNewFlowEntry - startCreateNewFlowEntry
622 , endSetProperties - startSetProperties, numProperties
623 , endSearchSwitch - startSearchSwitch
624 , endAddEdgeToSwitch - startAddEdgeToSwitch
625 , endSearchInPort - startSearchInPort
626 , endAddEdgeToInPort - startAddEdgeToInPort
627 , endSearchOutPort - startSearchOutPort
628 , endAddEdgeToOutPort - startAddEdgeToOutPort
629 , endAddEdgeBetweenFlowPath - startAddEdgeBetweenFlowPath
630 );
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700631 }
632
633 return flowEntryObj;
634 }
635
636 /**
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700637 * Delete a flow entry from the Network MAP.
638 *
639 * @param dbHandler the Graph Database handler to use.
640 * @param flowObj the corresponding Flow Path object for the Flow Entry.
641 * @param flowEntry the Flow Entry to delete.
642 * @return true on success, otherwise false.
643 */
yoshitomob292c622013-11-23 14:35:58 -0800644 static boolean deleteFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700645 IFlowPath flowObj,
646 FlowEntry flowEntry) {
647 IFlowEntry flowEntryObj = null;
648 try {
649 flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
650 } catch (Exception e) {
651 log.error(":deleteFlowEntry FlowEntryId:{} failed",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800652 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700653 return false;
654 }
655 //
656 // TODO: Don't print an error for now, because multiple controller
657 // instances might be deleting the same flow entry.
658 //
659 /*
660 if (flowEntryObj == null) {
661 log.error(":deleteFlowEntry FlowEntryId:{} failed: FlowEntry object not found",
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800662 flowEntry.flowEntryId());
Pavlin Radoslavov7407ab52013-11-01 22:19:00 -0700663 return false;
664 }
665 */
666 if (flowEntryObj == null)
667 return true;
668
669 flowObj.removeFlowEntry(flowEntryObj);
670 dbHandler.removeFlowEntry(flowEntryObj);
671 return true;
672 }
673
674 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700675 * Delete all previously added flows.
676 *
677 * @param dbHandler the Graph Database handler to use.
678 * @return true on success, otherwise false.
679 */
yoshitomob292c622013-11-23 14:35:58 -0800680 static boolean deleteAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700681 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
682 for (IFlowPath flowPathObj : allFlowPaths) {
683 if (flowPathObj == null)
684 continue;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700685
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800686 deleteIFlowPath(dbHandler, flowPathObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700687 }
Yuta HIGUCHI0cc22372014-01-13 14:54:00 -0800688 dbHandler.commit();
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700689
690 return true;
691 }
692
693 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800694 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700695 *
696 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800697 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700698 * @return true on success, otherwise false.
699 */
yoshitomob292c622013-11-23 14:35:58 -0800700 static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700701 IFlowPath flowObj = null;
702 try {
703 flowObj = dbHandler.searchFlowPath(flowId);
704 } catch (Exception e) {
705 // TODO: handle exceptions
706 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800707 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700708 return false;
709 }
710 if (flowObj == null) {
711 dbHandler.commit();
712 return true; // OK: No such flow
713 }
714
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800715 deleteIFlowPath(dbHandler, flowObj);
Yuta HIGUCHI0cc22372014-01-13 14:54:00 -0800716 dbHandler.commit();
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800717 return true;
718 }
719
Yuta HIGUCHIeab1c8b2014-01-15 19:13:28 -0800720 /**
721 * Delete a previously added flow.
722 * @note You need to call commit after calling this method.
723 * @param dbHandler the Graph Database handler to use.
724 * @param flowObj IFlowPath object to delete.
725 */
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800726 private static void deleteIFlowPath(DBOperation dbHandler, IFlowPath flowObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700727 //
728 // Remove all Flow Entries
729 //
730 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
731 for (IFlowEntry flowEntryObj : flowEntries) {
732 flowObj.removeFlowEntry(flowEntryObj);
733 dbHandler.removeFlowEntry(flowEntryObj);
734 }
735 // Remove the Flow itself
736 dbHandler.removeFlowPath(flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700737 }
738
739 /**
740 * Get a previously added flow.
741 *
742 * @param dbHandler the Graph Database handler to use.
743 * @param flowId the Flow ID of the flow to get.
744 * @return the Flow Path if found, otherwise null.
745 */
yoshitomob292c622013-11-23 14:35:58 -0800746 static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700747 IFlowPath flowObj = null;
748 try {
749 flowObj = dbHandler.searchFlowPath(flowId);
750 } catch (Exception e) {
751 // TODO: handle exceptions
752 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800753 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700754 return null;
755 }
756 if (flowObj == null) {
757 dbHandler.commit();
758 return null; // Flow not found
759 }
760
761 //
762 // Extract the Flow state
763 //
764 FlowPath flowPath = extractFlowPath(flowObj);
765 dbHandler.commit();
766
767 return flowPath;
768 }
769
770 /**
Pavlin Radoslavov52119fa2014-01-09 13:37:52 -0800771 * Get a previously added flow entry.
772 *
773 * @param dbHandler the Graph Database handler to use.
774 * @param flowEntryId the Flow Entry ID of the flow entry to get.
775 * @return the Flow Entry if found, otherwise null.
776 */
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800777 static FlowEntry getFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov52119fa2014-01-09 13:37:52 -0800778 FlowEntryId flowEntryId) {
779 IFlowEntry flowEntryObj = null;
780 try {
781 flowEntryObj = dbHandler.searchFlowEntry(flowEntryId);
782 } catch (Exception e) {
783 // TODO: handle exceptions
784 dbHandler.rollback();
785 log.error(":getFlowEntry FlowEntryId:{} failed", flowEntryId);
786 return null;
787 }
788 if (flowEntryObj == null) {
789 dbHandler.commit();
790 return null; // Flow not found
791 }
792
793 //
794 // Extract the Flow Entry state
795 //
796 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
797 dbHandler.commit();
798
799 return flowEntry;
800 }
801
802 /**
Pavlin Radoslavov8252fee2014-01-07 17:24:29 -0800803 * Get the source switch DPID of a previously added flow.
804 *
805 * @param dbHandler the Graph Database handler to use.
806 * @param flowId the Flow ID of the flow to get.
807 * @return the source switch DPID if found, otherwise null.
808 */
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800809 static Dpid getFlowSourceDpid(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov8252fee2014-01-07 17:24:29 -0800810 IFlowPath flowObj = null;
811 try {
812 flowObj = dbHandler.searchFlowPath(flowId);
813 } catch (Exception e) {
814 // TODO: handle exceptions
815 dbHandler.rollback();
816 log.error(":getFlowSourceDpid FlowId:{} failed", flowId);
817 return null;
818 }
819 if (flowObj == null) {
820 dbHandler.commit();
821 return null; // Flow not found
822 }
823
824 //
825 // Extract the Flow Source DPID
826 //
827 String srcSwitchStr = flowObj.getSrcSwitch();
828 if (srcSwitchStr == null) {
829 // TODO: A work-around, becauuse of some bogus database objects
830 dbHandler.commit();
831 return null;
832 }
833
834 Dpid dpid = new Dpid(srcSwitchStr);
835
836 dbHandler.commit();
837
838 return dpid;
839 }
840
841 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700842 * Get all installed flows by all installers.
843 *
844 * @param dbHandler the Graph Database handler to use.
845 * @return the Flow Paths if found, otherwise null.
846 */
yoshitomob292c622013-11-23 14:35:58 -0800847 static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700848 Iterable<IFlowPath> flowPathsObj = null;
849 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
850
851 try {
852 flowPathsObj = dbHandler.getAllFlowPaths();
853 } catch (Exception e) {
854 // TODO: handle exceptions
855 dbHandler.rollback();
856 log.error(":getAllFlowPaths failed");
857 return flowPaths;
858 }
859 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
860 dbHandler.commit();
861 return flowPaths; // No Flows found
862 }
863
864 for (IFlowPath flowObj : flowPathsObj) {
865 //
866 // Extract the Flow state
867 //
868 FlowPath flowPath = extractFlowPath(flowObj);
869 if (flowPath != null)
870 flowPaths.add(flowPath);
871 }
872
873 dbHandler.commit();
874
875 return flowPaths;
876 }
877
878 /**
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -0800879 * Get all installed flows whose Source Switch is controlled by this
880 * instance.
881 *
882 * @param dbHandler the Graph Database handler to use.
883 * @param mySwitches the collection of the switches controlled by this
884 * instance.
885 * @return the Flow Paths if found, otherwise null.
886 */
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800887 static ArrayList<FlowPath> getAllMyFlows(DBOperation dbHandler,
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -0800888 Map<Long, IOFSwitch> mySwitches) {
889 Iterable<IFlowPath> flowPathsObj = null;
890 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
891
892 try {
893 flowPathsObj = dbHandler.getAllFlowPaths();
894 } catch (Exception e) {
895 // TODO: handle exceptions
896 dbHandler.rollback();
897 log.error(":getAllMyFlowPaths failed");
898 return flowPaths;
899 }
900 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
901 dbHandler.commit();
902 return flowPaths; // No Flows found
903 }
904
905 for (IFlowPath flowObj : flowPathsObj) {
906 //
907 // Extract the Source Switch DPID and ignore if the switch
908 // is not controlled by this instance.
909 //
910 String srcSwitchStr = flowObj.getSrcSwitch();
911 if (srcSwitchStr == null) {
912 // TODO: A work-around, becauuse of some bogus database objects
913 continue;
914 }
915 Dpid dpid = new Dpid(srcSwitchStr);
916 if (mySwitches.get(dpid.value()) == null)
917 continue;
918
919 //
920 // Extract the Flow state
921 //
922 FlowPath flowPath = extractFlowPath(flowObj);
923 if (flowPath != null)
924 flowPaths.add(flowPath);
925 }
926
927 dbHandler.commit();
928
929 return flowPaths;
930 }
931
932 /**
Pavlin Radoslavovf3f23bb2014-01-10 13:02:33 -0800933 * Get a subset of installed flows.
934 *
935 * @param dbHandler the Graph Database handler to use.
936 * @param flowIds the collection of Flow IDs to get.
937 * @return the Flow Paths if found, otherwise null.
938 */
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800939 static ArrayList<FlowPath> getFlows(DBOperation dbHandler,
Pavlin Radoslavovf3f23bb2014-01-10 13:02:33 -0800940 Collection<FlowId> flowIds) {
941 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
942
943 // TODO: This implementation should use threads
944 for (FlowId flowId : flowIds) {
945 FlowPath flowPath = getFlow(dbHandler, flowId);
946 if (flowPath != null)
947 flowPaths.add(flowPath);
948 }
949 // dbHandler.commit();
950
951 return flowPaths;
952 }
953
954 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700955 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
956 *
957 * @param flowObj the object to extract the Flow Path State from.
958 * @return the extracted Flow Path State.
959 */
Brian O'Connor2c38efe2014-01-10 15:41:57 -0800960 static FlowPath extractFlowPath(IFlowPath flowObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700961 //
962 // Extract the Flow state
963 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800964 log.info("extractFlowPath: start");
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -0800965 String flowIdStr;
966 String installerIdStr;
967 String flowPathType;
968 String flowPathUserState;
969 Long flowPathFlags;
970 Integer idleTimeout;
971 Integer hardTimeout;
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800972 Integer priority;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -0800973 String srcSwitchStr;
974 Short srcPortShort;
975 String dstSwitchStr;
976 Short dstPortShort;
977
978 if ( flowObj.asVertex() instanceof RamCloudVertex ) {
979 RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
980 Map<String,Object> propMap = v.getProperties();
981
982 flowIdStr = (String) propMap.get("flow_id");
983 installerIdStr = (String) propMap.get("installer_id");
984 flowPathType = (String) propMap.get("flow_path_type");
985 flowPathUserState = (String) propMap.get("user_state");
986 flowPathFlags = (Long)propMap.get("flow_path_flags");
987 idleTimeout = (Integer) propMap.get("idle_timeout");
988 hardTimeout = (Integer) propMap.get("hard_timeout");
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800989 priority = (Integer) propMap.get("priority");
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -0800990 srcSwitchStr = (String) propMap.get("src_switch");
991 srcPortShort = (Short)propMap.get("src_port");
992 dstSwitchStr = (String) propMap.get("dst_switch");
993 dstPortShort = (Short)propMap.get("dst_port");
994 } else {
995 flowIdStr = flowObj.getFlowId();
996 installerIdStr = flowObj.getInstallerId();
997 flowPathType = flowObj.getFlowPathType();
998 flowPathUserState = flowObj.getFlowPathUserState();
999 flowPathFlags = flowObj.getFlowPathFlags();
1000 idleTimeout = flowObj.getIdleTimeout();
1001 hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001002 priority = flowObj.getPriority();
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001003 srcSwitchStr = flowObj.getSrcSwitch();
1004 srcPortShort = flowObj.getSrcPort();
1005 dstSwitchStr = flowObj.getDstSwitch();
1006 dstPortShort = flowObj.getDstPort();
1007 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001008
1009 if ((flowIdStr == null) ||
1010 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -07001011 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -07001012 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001013 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001014 (idleTimeout == null) ||
1015 (hardTimeout == null) ||
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001016 (priority == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001017 (srcSwitchStr == null) ||
1018 (srcPortShort == null) ||
1019 (dstSwitchStr == null) ||
1020 (dstPortShort == null)) {
Toshio Koidea9b25142014-01-10 01:15:57 -08001021 // TODO: A work-around, because of some bogus database objects
1022 log.error("extractFlowPath: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001023 return null;
1024 }
1025
1026 FlowPath flowPath = new FlowPath();
1027 flowPath.setFlowId(new FlowId(flowIdStr));
1028 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -07001029 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -07001030 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001031 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001032 flowPath.setIdleTimeout(idleTimeout);
1033 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001034 flowPath.setPriority(priority);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001035 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
1036 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
1037 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
1038 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
1039 //
1040 // Extract the match conditions common for all Flow Entries
1041 //
1042 {
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001043 FlowEntryMatch match = extractMatch(flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001044
1045 flowPath.setFlowEntryMatch(match);
1046 }
1047 //
1048 // Extract the actions for the first Flow Entry
1049 //
1050 {
1051 String actionsStr = flowObj.getActions();
1052 if (actionsStr != null) {
1053 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
1054 flowPath.setFlowEntryActions(flowEntryActions);
1055 }
1056 }
1057
1058 //
1059 // Extract all Flow Entries
1060 //
1061 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
1062 for (IFlowEntry flowEntryObj : flowEntries) {
1063 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
1064 if (flowEntry == null)
1065 continue;
1066 flowPath.dataPath().flowEntries().add(flowEntry);
1067 }
1068
Toshio Koidea9b25142014-01-10 01:15:57 -08001069 log.info("extractFlowPath: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001070 return flowPath;
1071 }
1072
1073 /**
1074 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
1075 *
1076 * @param flowEntryObj the object to extract the Flow Entry State from.
1077 * @return the extracted Flow Entry State.
1078 */
Brian O'Connora8e49802013-10-30 20:49:59 -07001079 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Toshio Koidea9b25142014-01-10 01:15:57 -08001080 log.info("extractFlowEntry: start");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001081 IFlowPath flowObj = flowEntryObj.getFlow();
Toshio Koidea9b25142014-01-10 01:15:57 -08001082 if (flowObj == null) {
1083 log.error("extractFlowEntry: no flowPath exists");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001084 return null;
Toshio Koidea9b25142014-01-10 01:15:57 -08001085 }
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001086
1087 String flowIdStr = flowObj.getFlowId();
1088 //
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001089 String flowEntryIdStr;
1090 Integer idleTimeout;
1091 Integer hardTimeout;
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001092 Integer priority;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001093 String switchDpidStr;
1094 String userState;
1095 String switchState;
1096 if ( flowEntryObj.asVertex() instanceof RamCloudVertex ) {
1097 RamCloudVertex v = (RamCloudVertex)flowEntryObj.asVertex();
1098 Map<String,Object> propMap = v.getProperties();
1099
1100 flowEntryIdStr = (String) propMap.get("flow_entry_id");
1101 idleTimeout = (Integer) propMap.get("idle_timeout");
1102 hardTimeout = (Integer) propMap.get("hard_timeout");
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001103 priority = (Integer) propMap.get("priority");
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001104 switchDpidStr = (String) propMap.get("switch_dpid");
1105 userState = (String) propMap.get("user_state");
1106 switchState = (String) propMap.get("switch_state");
1107 } else {
1108 flowEntryIdStr = flowEntryObj.getFlowEntryId();
1109 idleTimeout = flowEntryObj.getIdleTimeout();
1110 hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001111 priority = flowEntryObj.getPriority();
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001112 switchDpidStr = flowEntryObj.getSwitchDpid();
1113 userState = flowEntryObj.getUserState();
1114 switchState = flowEntryObj.getSwitchState();
1115 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001116
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001117 if ((flowIdStr == null) ||
1118 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001119 (idleTimeout == null) ||
1120 (hardTimeout == null) ||
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001121 (priority == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001122 (switchDpidStr == null) ||
1123 (userState == null) ||
1124 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -07001125 // TODO: A work-around, because of some bogus database objects
Toshio Koidea9b25142014-01-10 01:15:57 -08001126 log.error("extractFlowEntry: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001127 return null;
1128 }
1129
1130 FlowEntry flowEntry = new FlowEntry();
1131 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001132 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001133 flowEntry.setDpid(new Dpid(switchDpidStr));
yoshia97632b2013-12-17 15:46:08 -08001134 flowEntry.setIdleTimeout(idleTimeout);
1135 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001136 flowEntry.setPriority(priority);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001137
1138 //
1139 // Extract the match conditions
1140 //
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001141 FlowEntryMatch match = extractMatch(flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001142 flowEntry.setFlowEntryMatch(match);
1143
1144 //
1145 // Extract the actions
1146 //
1147 FlowEntryActions actions = new FlowEntryActions();
1148 String actionsStr = flowEntryObj.getActions();
1149 if (actionsStr != null)
1150 actions = new FlowEntryActions(actionsStr);
1151 flowEntry.setFlowEntryActions(actions);
1152 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
1153 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
1154 //
1155 // TODO: Take care of FlowEntryErrorState.
1156 //
Toshio Koidea9b25142014-01-10 01:15:57 -08001157 log.info("extractFlowEntry: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001158 return flowEntry;
1159 }
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001160
1161 /**
1162 * Extract FlowEntryMatch from IFlowPath or IFlowEntry
1163 * @param flowObj : either IFlowPath or IFlowEntry
1164 * @return extracted Match info
1165 */
1166 private static FlowEntryMatch extractMatch(IBaseObject flowObj) {
1167 FlowEntryMatch match = new FlowEntryMatch();
1168
1169 Short matchInPort = null; // Only for IFlowEntry
1170 String matchSrcMac = null;
1171 String matchDstMac = null;
1172 Short matchEthernetFrameType = null;
1173 Short matchVlanId = null;
1174 Byte matchVlanPriority = null;
1175 String matchSrcIPv4Net = null;
1176 String matchDstIPv4Net = null;
1177 Byte matchIpProto = null;
1178 Byte matchIpToS = null;
1179 Short matchSrcTcpUdpPort = null;
1180 Short matchDstTcpUdpPort = null;
1181
1182 if ( flowObj.asVertex() instanceof RamCloudVertex ) {
1183 RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
1184 Map<String,Object> propMap = v.getProperties();
1185 matchInPort = (Short) propMap.get("matchInPort");
1186 matchSrcMac = (String) propMap.get("matchSrcMac");
1187 matchDstMac = (String) propMap.get("matchDstMac");
1188 matchEthernetFrameType = (Short) propMap.get("matchEthernetFrameType");
1189 matchVlanId = (Short) propMap.get("matchVlanId");
1190 matchVlanPriority = (Byte) propMap.get("matchVlanPriority");
1191 matchSrcIPv4Net = (String) propMap.get("matchSrcIPv4Net");
1192 matchDstIPv4Net = (String) propMap.get("matchDstIPv4Net");
1193 matchIpProto = (Byte) propMap.get("matchIpProto");
1194 matchIpToS = (Byte) propMap.get("matchIpToS");
1195 matchSrcTcpUdpPort = (Short) propMap.get("matchSrcTcpUdpPort");
1196 matchDstTcpUdpPort = (Short) propMap.get("matchDstTcpUdpPort");
1197 } else {
1198 if (flowObj instanceof IFlowEntry ){
1199 IFlowEntry flowEntry = (IFlowEntry) flowObj;
1200 matchInPort = flowEntry.getMatchInPort();
1201 matchSrcMac = flowEntry.getMatchSrcMac();
1202 matchDstMac = flowEntry.getMatchDstMac();
1203 matchEthernetFrameType = flowEntry.getMatchEthernetFrameType();
1204 matchVlanId = flowEntry.getMatchVlanId();
1205 matchVlanPriority = flowEntry.getMatchVlanPriority();
1206 matchSrcIPv4Net = flowEntry.getMatchSrcIPv4Net();
1207 matchDstIPv4Net = flowEntry.getMatchDstIPv4Net();
1208 matchIpProto = flowEntry.getMatchIpProto();
1209 matchIpToS = flowEntry.getMatchIpToS();
1210 matchSrcTcpUdpPort = flowEntry.getMatchSrcTcpUdpPort();
1211 matchDstTcpUdpPort = flowEntry.getMatchDstTcpUdpPort();
1212 } else if(flowObj instanceof IFlowPath) {
1213 IFlowPath flowPath = (IFlowPath) flowObj;
1214 matchSrcMac = flowPath.getMatchSrcMac();
1215 matchDstMac = flowPath.getMatchDstMac();
1216 matchEthernetFrameType = flowPath.getMatchEthernetFrameType();
1217 matchVlanId = flowPath.getMatchVlanId();
1218 matchVlanPriority = flowPath.getMatchVlanPriority();
1219 matchSrcIPv4Net = flowPath.getMatchSrcIPv4Net();
1220 matchDstIPv4Net = flowPath.getMatchDstIPv4Net();
1221 matchIpProto = flowPath.getMatchIpProto();
1222 matchIpToS = flowPath.getMatchIpToS();
1223 matchSrcTcpUdpPort = flowPath.getMatchSrcTcpUdpPort();
1224 matchDstTcpUdpPort = flowPath.getMatchDstTcpUdpPort();
1225 }
1226 }
1227
1228 if (matchInPort != null)
1229 match.enableInPort(new Port(matchInPort));
1230 if (matchSrcMac != null)
1231 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
1232 if (matchDstMac != null)
1233 match.enableDstMac(MACAddress.valueOf(matchDstMac));
1234 if (matchEthernetFrameType != null)
1235 match.enableEthernetFrameType(matchEthernetFrameType);
1236 if (matchVlanId != null)
1237 match.enableVlanId(matchVlanId);
1238 if (matchVlanPriority != null)
1239 match.enableVlanPriority(matchVlanPriority);
1240 if (matchSrcIPv4Net != null)
1241 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
1242 if (matchDstIPv4Net != null)
1243 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
1244 if (matchIpProto != null)
1245 match.enableIpProto(matchIpProto);
1246 if (matchIpToS != null)
1247 match.enableIpToS(matchIpToS);
1248 if (matchSrcTcpUdpPort != null)
1249 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
1250 if (matchDstTcpUdpPort != null)
1251 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
1252 return match;
1253 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001254}