blob: 514e389fb729e0557a6c9df339960c16af0248e3 [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 Radoslavov12fd6f42014-02-03 10:05:22 -0800679 try {
680 // Get all Flow IDs
681 Iterable<IFlowPath> allFlowPaths = dbHandler.getAllFlowPaths();
682 for (IFlowPath flowPathObj : allFlowPaths) {
683 if (flowPathObj == null)
684 continue;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700685
Pavlin Radoslavov12fd6f42014-02-03 10:05:22 -0800686 deleteIFlowPath(dbHandler, flowPathObj);
687 }
688 dbHandler.commit();
689 } catch (Exception e) {
690 log.error("Exception deleting all Flow Paths from Network MAP: ", e);
691 return false;
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700692 }
693
694 return true;
695 }
696
697 /**
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800698 * Delete a previously added flow.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700699 *
700 * @param dbHandler the Graph Database handler to use.
Pavlin Radoslavovf2a52652013-11-22 12:35:42 -0800701 * @param flowId the Flow ID of the flow to delete.
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700702 * @return true on success, otherwise false.
703 */
yoshitomob292c622013-11-23 14:35:58 -0800704 static boolean deleteFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700705 IFlowPath flowObj = null;
706 try {
707 flowObj = dbHandler.searchFlowPath(flowId);
708 } catch (Exception e) {
709 // TODO: handle exceptions
710 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800711 log.error(":deleteFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700712 return false;
713 }
714 if (flowObj == null) {
715 dbHandler.commit();
716 return true; // OK: No such flow
717 }
718
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800719 deleteIFlowPath(dbHandler, flowObj);
Yuta HIGUCHI0cc22372014-01-13 14:54:00 -0800720 dbHandler.commit();
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800721 return true;
722 }
723
Yuta HIGUCHIeab1c8b2014-01-15 19:13:28 -0800724 /**
725 * Delete a previously added flow.
726 * @note You need to call commit after calling this method.
727 * @param dbHandler the Graph Database handler to use.
728 * @param flowObj IFlowPath object to delete.
729 */
Yuta HIGUCHI53794052014-01-10 16:49:41 -0800730 private static void deleteIFlowPath(DBOperation dbHandler, IFlowPath flowObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700731 //
732 // Remove all Flow Entries
733 //
734 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
735 for (IFlowEntry flowEntryObj : flowEntries) {
736 flowObj.removeFlowEntry(flowEntryObj);
737 dbHandler.removeFlowEntry(flowEntryObj);
738 }
739 // Remove the Flow itself
740 dbHandler.removeFlowPath(flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700741 }
742
743 /**
744 * Get a previously added flow.
745 *
746 * @param dbHandler the Graph Database handler to use.
747 * @param flowId the Flow ID of the flow to get.
748 * @return the Flow Path if found, otherwise null.
749 */
yoshitomob292c622013-11-23 14:35:58 -0800750 static FlowPath getFlow(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700751 IFlowPath flowObj = null;
752 try {
753 flowObj = dbHandler.searchFlowPath(flowId);
754 } catch (Exception e) {
755 // TODO: handle exceptions
756 dbHandler.rollback();
Yuta HIGUCHI5302ddf2014-01-06 12:53:35 -0800757 log.error(":getFlow FlowId:{} failed", flowId);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700758 return null;
759 }
760 if (flowObj == null) {
761 dbHandler.commit();
762 return null; // Flow not found
763 }
764
765 //
766 // Extract the Flow state
767 //
768 FlowPath flowPath = extractFlowPath(flowObj);
769 dbHandler.commit();
770
771 return flowPath;
772 }
773
774 /**
Pavlin Radoslavov52119fa2014-01-09 13:37:52 -0800775 * Get a previously added flow entry.
776 *
777 * @param dbHandler the Graph Database handler to use.
778 * @param flowEntryId the Flow Entry ID of the flow entry to get.
779 * @return the Flow Entry if found, otherwise null.
780 */
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800781 static FlowEntry getFlowEntry(DBOperation dbHandler,
Pavlin Radoslavov52119fa2014-01-09 13:37:52 -0800782 FlowEntryId flowEntryId) {
783 IFlowEntry flowEntryObj = null;
784 try {
785 flowEntryObj = dbHandler.searchFlowEntry(flowEntryId);
786 } catch (Exception e) {
787 // TODO: handle exceptions
788 dbHandler.rollback();
789 log.error(":getFlowEntry FlowEntryId:{} failed", flowEntryId);
790 return null;
791 }
792 if (flowEntryObj == null) {
793 dbHandler.commit();
794 return null; // Flow not found
795 }
796
797 //
798 // Extract the Flow Entry state
799 //
800 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
801 dbHandler.commit();
802
803 return flowEntry;
804 }
805
806 /**
Pavlin Radoslavov8252fee2014-01-07 17:24:29 -0800807 * Get the source switch DPID of a previously added flow.
808 *
809 * @param dbHandler the Graph Database handler to use.
810 * @param flowId the Flow ID of the flow to get.
811 * @return the source switch DPID if found, otherwise null.
812 */
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800813 static Dpid getFlowSourceDpid(DBOperation dbHandler, FlowId flowId) {
Pavlin Radoslavov8252fee2014-01-07 17:24:29 -0800814 IFlowPath flowObj = null;
815 try {
816 flowObj = dbHandler.searchFlowPath(flowId);
817 } catch (Exception e) {
818 // TODO: handle exceptions
819 dbHandler.rollback();
820 log.error(":getFlowSourceDpid FlowId:{} failed", flowId);
821 return null;
822 }
823 if (flowObj == null) {
824 dbHandler.commit();
825 return null; // Flow not found
826 }
827
828 //
829 // Extract the Flow Source DPID
830 //
831 String srcSwitchStr = flowObj.getSrcSwitch();
832 if (srcSwitchStr == null) {
833 // TODO: A work-around, becauuse of some bogus database objects
834 dbHandler.commit();
835 return null;
836 }
837
838 Dpid dpid = new Dpid(srcSwitchStr);
839
840 dbHandler.commit();
841
842 return dpid;
843 }
844
845 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700846 * Get all installed flows by all installers.
847 *
848 * @param dbHandler the Graph Database handler to use.
849 * @return the Flow Paths if found, otherwise null.
850 */
yoshitomob292c622013-11-23 14:35:58 -0800851 static ArrayList<FlowPath> getAllFlows(DBOperation dbHandler) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700852 Iterable<IFlowPath> flowPathsObj = null;
853 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
854
855 try {
856 flowPathsObj = dbHandler.getAllFlowPaths();
857 } catch (Exception e) {
858 // TODO: handle exceptions
859 dbHandler.rollback();
860 log.error(":getAllFlowPaths failed");
861 return flowPaths;
862 }
863 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
864 dbHandler.commit();
865 return flowPaths; // No Flows found
866 }
867
868 for (IFlowPath flowObj : flowPathsObj) {
869 //
870 // Extract the Flow state
871 //
872 FlowPath flowPath = extractFlowPath(flowObj);
873 if (flowPath != null)
874 flowPaths.add(flowPath);
875 }
876
877 dbHandler.commit();
878
879 return flowPaths;
880 }
881
882 /**
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -0800883 * Get all installed flows whose Source Switch is controlled by this
884 * instance.
885 *
886 * @param dbHandler the Graph Database handler to use.
887 * @param mySwitches the collection of the switches controlled by this
888 * instance.
889 * @return the Flow Paths if found, otherwise null.
890 */
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800891 static ArrayList<FlowPath> getAllMyFlows(DBOperation dbHandler,
Pavlin Radoslavov16b761d2014-01-08 09:47:14 -0800892 Map<Long, IOFSwitch> mySwitches) {
893 Iterable<IFlowPath> flowPathsObj = null;
894 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
895
896 try {
897 flowPathsObj = dbHandler.getAllFlowPaths();
898 } catch (Exception e) {
899 // TODO: handle exceptions
900 dbHandler.rollback();
901 log.error(":getAllMyFlowPaths failed");
902 return flowPaths;
903 }
904 if ((flowPathsObj == null) || (flowPathsObj.iterator().hasNext() == false)) {
905 dbHandler.commit();
906 return flowPaths; // No Flows found
907 }
908
909 for (IFlowPath flowObj : flowPathsObj) {
910 //
911 // Extract the Source Switch DPID and ignore if the switch
912 // is not controlled by this instance.
913 //
914 String srcSwitchStr = flowObj.getSrcSwitch();
915 if (srcSwitchStr == null) {
916 // TODO: A work-around, becauuse of some bogus database objects
917 continue;
918 }
919 Dpid dpid = new Dpid(srcSwitchStr);
920 if (mySwitches.get(dpid.value()) == null)
921 continue;
922
923 //
924 // Extract the Flow state
925 //
926 FlowPath flowPath = extractFlowPath(flowObj);
927 if (flowPath != null)
928 flowPaths.add(flowPath);
929 }
930
931 dbHandler.commit();
932
933 return flowPaths;
934 }
935
936 /**
Pavlin Radoslavovf3f23bb2014-01-10 13:02:33 -0800937 * Get a subset of installed flows.
938 *
939 * @param dbHandler the Graph Database handler to use.
940 * @param flowIds the collection of Flow IDs to get.
941 * @return the Flow Paths if found, otherwise null.
942 */
Yuta HIGUCHI337e46d2014-01-10 22:49:27 -0800943 static ArrayList<FlowPath> getFlows(DBOperation dbHandler,
Pavlin Radoslavovf3f23bb2014-01-10 13:02:33 -0800944 Collection<FlowId> flowIds) {
945 ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
946
947 // TODO: This implementation should use threads
948 for (FlowId flowId : flowIds) {
949 FlowPath flowPath = getFlow(dbHandler, flowId);
950 if (flowPath != null)
951 flowPaths.add(flowPath);
952 }
953 // dbHandler.commit();
954
955 return flowPaths;
956 }
957
958 /**
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700959 * Extract Flow Path State from a Titan Database Object @ref IFlowPath.
960 *
961 * @param flowObj the object to extract the Flow Path State from.
962 * @return the extracted Flow Path State.
963 */
Brian O'Connor2c38efe2014-01-10 15:41:57 -0800964 static FlowPath extractFlowPath(IFlowPath flowObj) {
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -0700965 //
966 // Extract the Flow state
967 //
Toshio Koidea9b25142014-01-10 01:15:57 -0800968 log.info("extractFlowPath: start");
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -0800969 String flowIdStr;
970 String installerIdStr;
971 String flowPathType;
972 String flowPathUserState;
973 Long flowPathFlags;
974 Integer idleTimeout;
975 Integer hardTimeout;
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800976 Integer priority;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -0800977 String srcSwitchStr;
978 Short srcPortShort;
979 String dstSwitchStr;
980 Short dstPortShort;
981
982 if ( flowObj.asVertex() instanceof RamCloudVertex ) {
983 RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
984 Map<String,Object> propMap = v.getProperties();
985
986 flowIdStr = (String) propMap.get("flow_id");
987 installerIdStr = (String) propMap.get("installer_id");
988 flowPathType = (String) propMap.get("flow_path_type");
989 flowPathUserState = (String) propMap.get("user_state");
990 flowPathFlags = (Long)propMap.get("flow_path_flags");
991 idleTimeout = (Integer) propMap.get("idle_timeout");
992 hardTimeout = (Integer) propMap.get("hard_timeout");
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -0800993 priority = (Integer) propMap.get("priority");
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -0800994 srcSwitchStr = (String) propMap.get("src_switch");
995 srcPortShort = (Short)propMap.get("src_port");
996 dstSwitchStr = (String) propMap.get("dst_switch");
997 dstPortShort = (Short)propMap.get("dst_port");
998 } else {
999 flowIdStr = flowObj.getFlowId();
1000 installerIdStr = flowObj.getInstallerId();
1001 flowPathType = flowObj.getFlowPathType();
1002 flowPathUserState = flowObj.getFlowPathUserState();
1003 flowPathFlags = flowObj.getFlowPathFlags();
1004 idleTimeout = flowObj.getIdleTimeout();
1005 hardTimeout = flowObj.getHardTimeout();
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001006 priority = flowObj.getPriority();
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001007 srcSwitchStr = flowObj.getSrcSwitch();
1008 srcPortShort = flowObj.getSrcPort();
1009 dstSwitchStr = flowObj.getDstSwitch();
1010 dstPortShort = flowObj.getDstPort();
1011 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001012
1013 if ((flowIdStr == null) ||
1014 (installerIdStr == null) ||
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -07001015 (flowPathType == null) ||
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -07001016 (flowPathUserState == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001017 (flowPathFlags == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001018 (idleTimeout == null) ||
1019 (hardTimeout == null) ||
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001020 (priority == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001021 (srcSwitchStr == null) ||
1022 (srcPortShort == null) ||
1023 (dstSwitchStr == null) ||
1024 (dstPortShort == null)) {
Toshio Koidea9b25142014-01-10 01:15:57 -08001025 // TODO: A work-around, because of some bogus database objects
1026 log.error("extractFlowPath: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001027 return null;
1028 }
1029
1030 FlowPath flowPath = new FlowPath();
1031 flowPath.setFlowId(new FlowId(flowIdStr));
1032 flowPath.setInstallerId(new CallerId(installerIdStr));
Pavlin Radoslavovd28cf7c2013-10-26 11:27:43 -07001033 flowPath.setFlowPathType(FlowPathType.valueOf(flowPathType));
Pavlin Radoslavov7d4a40e2013-10-27 23:39:40 -07001034 flowPath.setFlowPathUserState(FlowPathUserState.valueOf(flowPathUserState));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001035 flowPath.setFlowPathFlags(new FlowPathFlags(flowPathFlags));
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001036 flowPath.setIdleTimeout(idleTimeout);
1037 flowPath.setHardTimeout(hardTimeout);
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001038 flowPath.setPriority(priority);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001039 flowPath.dataPath().srcPort().setDpid(new Dpid(srcSwitchStr));
1040 flowPath.dataPath().srcPort().setPort(new Port(srcPortShort));
1041 flowPath.dataPath().dstPort().setDpid(new Dpid(dstSwitchStr));
1042 flowPath.dataPath().dstPort().setPort(new Port(dstPortShort));
1043 //
1044 // Extract the match conditions common for all Flow Entries
1045 //
1046 {
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001047 FlowEntryMatch match = extractMatch(flowObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001048
1049 flowPath.setFlowEntryMatch(match);
1050 }
1051 //
1052 // Extract the actions for the first Flow Entry
1053 //
1054 {
1055 String actionsStr = flowObj.getActions();
1056 if (actionsStr != null) {
1057 FlowEntryActions flowEntryActions = new FlowEntryActions(actionsStr);
1058 flowPath.setFlowEntryActions(flowEntryActions);
1059 }
1060 }
1061
1062 //
1063 // Extract all Flow Entries
1064 //
1065 Iterable<IFlowEntry> flowEntries = flowObj.getFlowEntries();
1066 for (IFlowEntry flowEntryObj : flowEntries) {
1067 FlowEntry flowEntry = extractFlowEntry(flowEntryObj);
1068 if (flowEntry == null)
1069 continue;
1070 flowPath.dataPath().flowEntries().add(flowEntry);
1071 }
1072
Toshio Koidea9b25142014-01-10 01:15:57 -08001073 log.info("extractFlowPath: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001074 return flowPath;
1075 }
1076
1077 /**
1078 * Extract Flow Entry State from a Titan Database Object @ref IFlowEntry.
1079 *
1080 * @param flowEntryObj the object to extract the Flow Entry State from.
1081 * @return the extracted Flow Entry State.
1082 */
Brian O'Connora8e49802013-10-30 20:49:59 -07001083 public static FlowEntry extractFlowEntry(IFlowEntry flowEntryObj) {
Toshio Koidea9b25142014-01-10 01:15:57 -08001084 log.info("extractFlowEntry: start");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001085 IFlowPath flowObj = flowEntryObj.getFlow();
Toshio Koidea9b25142014-01-10 01:15:57 -08001086 if (flowObj == null) {
1087 log.error("extractFlowEntry: no flowPath exists");
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001088 return null;
Toshio Koidea9b25142014-01-10 01:15:57 -08001089 }
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001090
1091 String flowIdStr = flowObj.getFlowId();
1092 //
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001093 String flowEntryIdStr;
1094 Integer idleTimeout;
1095 Integer hardTimeout;
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001096 Integer priority;
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001097 String switchDpidStr;
1098 String userState;
1099 String switchState;
1100 if ( flowEntryObj.asVertex() instanceof RamCloudVertex ) {
1101 RamCloudVertex v = (RamCloudVertex)flowEntryObj.asVertex();
1102 Map<String,Object> propMap = v.getProperties();
1103
1104 flowEntryIdStr = (String) propMap.get("flow_entry_id");
1105 idleTimeout = (Integer) propMap.get("idle_timeout");
1106 hardTimeout = (Integer) propMap.get("hard_timeout");
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001107 priority = (Integer) propMap.get("priority");
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001108 switchDpidStr = (String) propMap.get("switch_dpid");
1109 userState = (String) propMap.get("user_state");
1110 switchState = (String) propMap.get("switch_state");
1111 } else {
1112 flowEntryIdStr = flowEntryObj.getFlowEntryId();
1113 idleTimeout = flowEntryObj.getIdleTimeout();
1114 hardTimeout = flowEntryObj.getHardTimeout();
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001115 priority = flowEntryObj.getPriority();
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001116 switchDpidStr = flowEntryObj.getSwitchDpid();
1117 userState = flowEntryObj.getUserState();
1118 switchState = flowEntryObj.getSwitchState();
1119 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001120
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001121 if ((flowIdStr == null) ||
1122 (flowEntryIdStr == null) ||
Pavlin Radoslavov5139c0b2013-12-09 18:04:53 -08001123 (idleTimeout == null) ||
1124 (hardTimeout == null) ||
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001125 (priority == null) ||
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001126 (switchDpidStr == null) ||
1127 (userState == null) ||
1128 (switchState == null)) {
Brian O'Connora8e49802013-10-30 20:49:59 -07001129 // TODO: A work-around, because of some bogus database objects
Toshio Koidea9b25142014-01-10 01:15:57 -08001130 log.error("extractFlowEntry: wrong properties");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001131 return null;
1132 }
1133
1134 FlowEntry flowEntry = new FlowEntry();
1135 flowEntry.setFlowEntryId(new FlowEntryId(flowEntryIdStr));
Pavlin Radoslavovcf87e532013-12-13 18:17:00 -08001136 flowEntry.setFlowId(new FlowId(flowIdStr));
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001137 flowEntry.setDpid(new Dpid(switchDpidStr));
yoshia97632b2013-12-17 15:46:08 -08001138 flowEntry.setIdleTimeout(idleTimeout);
1139 flowEntry.setHardTimeout(hardTimeout);
Pavlin Radoslavovafbf1032014-02-04 10:37:52 -08001140 flowEntry.setPriority(priority);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001141
1142 //
1143 // Extract the match conditions
1144 //
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001145 FlowEntryMatch match = extractMatch(flowEntryObj);
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001146 flowEntry.setFlowEntryMatch(match);
1147
1148 //
1149 // Extract the actions
1150 //
1151 FlowEntryActions actions = new FlowEntryActions();
1152 String actionsStr = flowEntryObj.getActions();
1153 if (actionsStr != null)
1154 actions = new FlowEntryActions(actionsStr);
1155 flowEntry.setFlowEntryActions(actions);
1156 flowEntry.setFlowEntryUserState(FlowEntryUserState.valueOf(userState));
1157 flowEntry.setFlowEntrySwitchState(FlowEntrySwitchState.valueOf(switchState));
1158 //
1159 // TODO: Take care of FlowEntryErrorState.
1160 //
Toshio Koidea9b25142014-01-10 01:15:57 -08001161 log.info("extractFlowEntry: end");
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001162 return flowEntry;
1163 }
Yuta HIGUCHIcb32b2a2014-01-10 18:07:33 -08001164
1165 /**
1166 * Extract FlowEntryMatch from IFlowPath or IFlowEntry
1167 * @param flowObj : either IFlowPath or IFlowEntry
1168 * @return extracted Match info
1169 */
1170 private static FlowEntryMatch extractMatch(IBaseObject flowObj) {
1171 FlowEntryMatch match = new FlowEntryMatch();
1172
1173 Short matchInPort = null; // Only for IFlowEntry
1174 String matchSrcMac = null;
1175 String matchDstMac = null;
1176 Short matchEthernetFrameType = null;
1177 Short matchVlanId = null;
1178 Byte matchVlanPriority = null;
1179 String matchSrcIPv4Net = null;
1180 String matchDstIPv4Net = null;
1181 Byte matchIpProto = null;
1182 Byte matchIpToS = null;
1183 Short matchSrcTcpUdpPort = null;
1184 Short matchDstTcpUdpPort = null;
1185
1186 if ( flowObj.asVertex() instanceof RamCloudVertex ) {
1187 RamCloudVertex v = (RamCloudVertex)flowObj.asVertex();
1188 Map<String,Object> propMap = v.getProperties();
1189 matchInPort = (Short) propMap.get("matchInPort");
1190 matchSrcMac = (String) propMap.get("matchSrcMac");
1191 matchDstMac = (String) propMap.get("matchDstMac");
1192 matchEthernetFrameType = (Short) propMap.get("matchEthernetFrameType");
1193 matchVlanId = (Short) propMap.get("matchVlanId");
1194 matchVlanPriority = (Byte) propMap.get("matchVlanPriority");
1195 matchSrcIPv4Net = (String) propMap.get("matchSrcIPv4Net");
1196 matchDstIPv4Net = (String) propMap.get("matchDstIPv4Net");
1197 matchIpProto = (Byte) propMap.get("matchIpProto");
1198 matchIpToS = (Byte) propMap.get("matchIpToS");
1199 matchSrcTcpUdpPort = (Short) propMap.get("matchSrcTcpUdpPort");
1200 matchDstTcpUdpPort = (Short) propMap.get("matchDstTcpUdpPort");
1201 } else {
1202 if (flowObj instanceof IFlowEntry ){
1203 IFlowEntry flowEntry = (IFlowEntry) flowObj;
1204 matchInPort = flowEntry.getMatchInPort();
1205 matchSrcMac = flowEntry.getMatchSrcMac();
1206 matchDstMac = flowEntry.getMatchDstMac();
1207 matchEthernetFrameType = flowEntry.getMatchEthernetFrameType();
1208 matchVlanId = flowEntry.getMatchVlanId();
1209 matchVlanPriority = flowEntry.getMatchVlanPriority();
1210 matchSrcIPv4Net = flowEntry.getMatchSrcIPv4Net();
1211 matchDstIPv4Net = flowEntry.getMatchDstIPv4Net();
1212 matchIpProto = flowEntry.getMatchIpProto();
1213 matchIpToS = flowEntry.getMatchIpToS();
1214 matchSrcTcpUdpPort = flowEntry.getMatchSrcTcpUdpPort();
1215 matchDstTcpUdpPort = flowEntry.getMatchDstTcpUdpPort();
1216 } else if(flowObj instanceof IFlowPath) {
1217 IFlowPath flowPath = (IFlowPath) flowObj;
1218 matchSrcMac = flowPath.getMatchSrcMac();
1219 matchDstMac = flowPath.getMatchDstMac();
1220 matchEthernetFrameType = flowPath.getMatchEthernetFrameType();
1221 matchVlanId = flowPath.getMatchVlanId();
1222 matchVlanPriority = flowPath.getMatchVlanPriority();
1223 matchSrcIPv4Net = flowPath.getMatchSrcIPv4Net();
1224 matchDstIPv4Net = flowPath.getMatchDstIPv4Net();
1225 matchIpProto = flowPath.getMatchIpProto();
1226 matchIpToS = flowPath.getMatchIpToS();
1227 matchSrcTcpUdpPort = flowPath.getMatchSrcTcpUdpPort();
1228 matchDstTcpUdpPort = flowPath.getMatchDstTcpUdpPort();
1229 }
1230 }
1231
1232 if (matchInPort != null)
1233 match.enableInPort(new Port(matchInPort));
1234 if (matchSrcMac != null)
1235 match.enableSrcMac(MACAddress.valueOf(matchSrcMac));
1236 if (matchDstMac != null)
1237 match.enableDstMac(MACAddress.valueOf(matchDstMac));
1238 if (matchEthernetFrameType != null)
1239 match.enableEthernetFrameType(matchEthernetFrameType);
1240 if (matchVlanId != null)
1241 match.enableVlanId(matchVlanId);
1242 if (matchVlanPriority != null)
1243 match.enableVlanPriority(matchVlanPriority);
1244 if (matchSrcIPv4Net != null)
1245 match.enableSrcIPv4Net(new IPv4Net(matchSrcIPv4Net));
1246 if (matchDstIPv4Net != null)
1247 match.enableDstIPv4Net(new IPv4Net(matchDstIPv4Net));
1248 if (matchIpProto != null)
1249 match.enableIpProto(matchIpProto);
1250 if (matchIpToS != null)
1251 match.enableIpToS(matchIpToS);
1252 if (matchSrcTcpUdpPort != null)
1253 match.enableSrcTcpUdpPort(matchSrcTcpUdpPort);
1254 if (matchDstTcpUdpPort != null)
1255 match.enableDstTcpUdpPort(matchDstTcpUdpPort);
1256 return match;
1257 }
Pavlin Radoslavov661c86f2013-10-21 12:40:40 -07001258}