blob: 2307e6570e6932afc91ed93d751e49ba10d564da [file] [log] [blame]
Jonathan Hartaa380972014-04-03 10:24:46 -07001package net.onrc.onos.core.intent;
Brian O'Connor7f8e3012014-02-15 23:59:29 -08002
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07003import java.util.ArrayList;
Brian O'Connor7f8e3012014-02-15 23:59:29 -08004import java.util.HashSet;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -07005import java.util.List;
Brian O'Connora84723c2014-06-13 00:26:49 -07006import java.util.Objects;
Brian O'Connor7f8e3012014-02-15 23:59:29 -08007import java.util.Set;
8
9import net.floodlightcontroller.util.MACAddress;
Jonathan Hartaa380972014-04-03 10:24:46 -070010import net.onrc.onos.core.intent.IntentOperation.Operator;
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070011
12import org.projectfloodlight.openflow.protocol.OFActionType;
13import org.projectfloodlight.openflow.protocol.OFFactory;
14import org.projectfloodlight.openflow.protocol.OFFlowMod;
15import org.projectfloodlight.openflow.protocol.action.OFAction;
16import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
17import org.projectfloodlight.openflow.protocol.match.Match.Builder;
18import org.projectfloodlight.openflow.types.OFBufferId;
19import org.projectfloodlight.openflow.types.OFPort;
20import org.projectfloodlight.openflow.types.U64;
Brian O'Connor7f8e3012014-02-15 23:59:29 -080021
22/**
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070023 * A class to represent an OpenFlow FlowMod. <br>
Brian O'Connora84723c2014-06-13 00:26:49 -070024 * It is OpenFlow v.1.0-centric and contains a Match and an Action.
Brian O'Connor7f8e3012014-02-15 23:59:29 -080025 */
26
27public class FlowEntry {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070028 public static final int PRIORITY_DEFAULT = 32768; // Default Flow Priority
29
Ray Milkey269ffb92014-04-03 14:43:30 -070030 protected long sw;
31 protected Match match;
32 protected Set<Action> actions;
33 protected Operator operator;
TeruU30c0c932014-05-15 16:47:41 -070034 protected int hardTimeout = 0;
35 protected int idleTimeout = 0;
TeruU9e530662014-05-18 11:49:37 -070036 protected long flowEntryId;
Ray Milkey269ffb92014-04-03 14:43:30 -070037
Brian O'Connora84723c2014-06-13 00:26:49 -070038 /**
39 * Constructor.
40 *
41 * @param sw switch's DPID
42 * @param srcPort source port on switch
43 * @param dstPort output port on switch
44 * @param srcMac source Ethernet MAC address
45 * @param dstMac destination Ethernet MAC address
46 * @param srcIpAddress source IP address
47 * @param dstIpAddress destination IP address
48 * @param operator OpenFlow operation/command (add, remove, etc.)
49 */
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070050 // CHECKSTYLE:OFF suppress the warning about too many parameters
Ray Milkey269ffb92014-04-03 14:43:30 -070051 public FlowEntry(long sw, long srcPort, long dstPort,
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070052 MACAddress srcMac, MACAddress dstMac,
53 int srcIpAddress, int dstIpAddress,
54 Operator operator) {
55 // CHECKSTYLE:ON
Ray Milkey269ffb92014-04-03 14:43:30 -070056 this.sw = sw;
Komal Shah399a2922014-05-28 01:57:40 -070057 this.match = new Match(sw, srcPort, srcMac, dstMac, srcIpAddress, dstIpAddress);
Ray Milkey269ffb92014-04-03 14:43:30 -070058 this.actions = new HashSet<Action>();
59 this.actions.add(new ForwardAction(dstPort));
60 this.operator = operator;
TeruU9e530662014-05-18 11:49:37 -070061 this.flowEntryId = hashCode();
Ray Milkey269ffb92014-04-03 14:43:30 -070062 }
63
Brian O'Connora84723c2014-06-13 00:26:49 -070064 /**
65 * Gets the switch for this FlowEntry.
66 *
67 * @return the switch's DPID
68 */
69 public long getSwitch() {
70 return sw;
71 }
72
73 /**
74 * Gets the operator (i.e. add, remove, error).
75 *
76 * @return the operator
77 */
78 public Operator getOperator() {
79 return operator;
80 }
81
82 /**
83 * Sets the FlowMod operation (i.e. add, remove, error).
84 *
85 * @param op the operator
86 */
87 public void setOperator(Operator op) {
88 operator = op;
89 }
90
91 /**
TeruU30c0c932014-05-15 16:47:41 -070092 * Gets hard timeout value in seconds.
93 *
TeruU9e530662014-05-18 11:49:37 -070094 * @return the hard timeout value in seconds
TeruU30c0c932014-05-15 16:47:41 -070095 */
96 public int getHardTimeout() {
97 return hardTimeout;
98 }
99
Brian O'Connora84723c2014-06-13 00:26:49 -0700100 /**
TeruU30c0c932014-05-15 16:47:41 -0700101 * Sets hard timeout value in seconds.
102 *
Sho SHIMIZUa1199fa2014-06-10 18:11:12 -0700103 * @param hardTimeout hard timeout value in seconds
TeruU30c0c932014-05-15 16:47:41 -0700104 */
105 public void setHardTimeout(int hardTimeout) {
106 this.hardTimeout = hardTimeout;
107 }
108
Brian O'Connora84723c2014-06-13 00:26:49 -0700109 /**
110 * Gets idle timeout value in seconds.
111 *
112 * @return the idle timeout value in seconds
113 */
114 public int getIdleTimeout() {
115 return idleTimeout;
116 }
117
118 /**
TeruU30c0c932014-05-15 16:47:41 -0700119 * Sets idle timeout value in seconds.
120 *
Sho SHIMIZUa1199fa2014-06-10 18:11:12 -0700121 * @param idleTimeout idle timeout value in seconds
TeruU30c0c932014-05-15 16:47:41 -0700122 */
123 public void setIdleTimeout(int idleTimeout) {
124 this.idleTimeout = idleTimeout;
125 }
126
Brian O'Connora84723c2014-06-13 00:26:49 -0700127 /**
TeruU9e530662014-05-18 11:49:37 -0700128 * Gets flowEntryId.
129 *
Brian O'Connora84723c2014-06-13 00:26:49 -0700130 * @return the flowEntryId to be set in cookie
TeruU9e530662014-05-18 11:49:37 -0700131 */
132 public long getFlowEntryId() {
133 return flowEntryId;
134 }
135
Brian O'Connora84723c2014-06-13 00:26:49 -0700136 /**
TeruU9e530662014-05-18 11:49:37 -0700137 * Sets flowEntryId.
138 *
Sho SHIMIZUa1199fa2014-06-10 18:11:12 -0700139 * @param flowEntryId flowEntryId to be set in cookie
TeruU9e530662014-05-18 11:49:37 -0700140 */
141 public void setFlowEntryId(long flowEntryId) {
142 this.flowEntryId = flowEntryId;
143 }
144
Brian O'Connora84723c2014-06-13 00:26:49 -0700145 /**
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700146 * Builds and returns an OFFlowMod given an OFFactory.
Brian O'Connora84723c2014-06-13 00:26:49 -0700147 *
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700148 * @param factory the OFFactory to use for building
149 * @return the OFFlowMod
Brian O'Connora84723c2014-06-13 00:26:49 -0700150 */
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700151 public OFFlowMod buildFlowMod(OFFactory factory) {
152 OFFlowMod.Builder builder = null;
153
Ray Milkey269ffb92014-04-03 14:43:30 -0700154 switch (operator) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700155 case ADD:
156 builder = factory.buildFlowModifyStrict();
157 break;
158 case REMOVE:
159 builder = factory.buildFlowDeleteStrict();
160 break;
161 default:
162 // TODO throw error?
163 return null;
Ray Milkey269ffb92014-04-03 14:43:30 -0700164 }
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700165
166 // Build OFMatch
167 Builder matchBuilder = match.getOFMatchBuilder(factory);
168
169 // Build OFAction Set
170 List<OFAction> actionList = new ArrayList<>(actions.size());
171 for (Action action : actions) {
172 actionList.add(action.getOFAction(factory));
173 }
174
175 OFPort outp = OFPort.of((short) 0xffff); // OF1.0 OFPP.NONE
176 if (operator == Operator.REMOVE) {
177 if (actionList.size() == 1) {
178 if (actionList.get(0).getType() == OFActionType.OUTPUT) {
179 OFActionOutput oa = (OFActionOutput) actionList.get(0);
180 outp = oa.getPort();
181 }
182 }
183 }
184
185 // Build OFFlowMod
186 builder.setMatch(matchBuilder.build())
187 .setActions(actionList)
188 .setIdleTimeout(idleTimeout)
189 .setHardTimeout(hardTimeout)
190 .setCookie(U64.of(flowEntryId))
191 .setBufferId(OFBufferId.NO_BUFFER)
192 .setPriority(PRIORITY_DEFAULT)
193 .setOutPort(outp);
194
195 /* Note: The following are NOT USED.
196 * builder.setFlags()
197 * builder.setInstructions()
198 * builder.setOutGroup()
199 * builder.setTableId()
200 * builder.setXid()
201 */
202
203 // TODO from Flow Pusher
204 // Set the OFPFF_SEND_FLOW_REM flag if the Flow Entry is not
205 // permanent.
206 //
207 // if ((flowEntry.idleTimeout() != 0) ||
208 // (flowEntry.hardTimeout() != 0)) {
209 // fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
210 // }
211
212 // TODO do we care?
213 // fm.setOutPort(OFPort.OFPP_NONE.getValue());
214 // if ((flowModCommand == OFFlowMod.OFPFC_DELETE)
215 // || (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
216 // if (actionOutputPort.portNumber != null) {
217 // fm.setOutPort(actionOutputPort.portNumber);
218 // }
219 // }
220
221 // TODO
222 // Set the OFPFF_SEND_FLOW_REM flag if the Flow Entry is not
223 // permanent.
224 //
225 // if ((flowEntry.idleTimeout() != 0) ||
226 // (flowEntry.hardTimeout() != 0)) {
227 // fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
228 // }
229
230 return builder.build();
Ray Milkey269ffb92014-04-03 14:43:30 -0700231 }
232
Brian O'Connora84723c2014-06-13 00:26:49 -0700233 /**
234 * Returns a String representation of this FlowEntry.
235 *
236 * @return the FlowEntry as a String
237 */
TeruU30c0c932014-05-15 16:47:41 -0700238 @Override
Brian O'Connora84723c2014-06-13 00:26:49 -0700239 public String toString() {
240 return match + "->" + actions;
Ray Milkey269ffb92014-04-03 14:43:30 -0700241 }
242
Brian O'Connora84723c2014-06-13 00:26:49 -0700243 /**
244 * Generates hash using Objects.hash() on the match and actions.
245 */
246 @Override
Ray Milkey4373cbe2014-08-12 09:58:58 -0700247 public final int hashCode() {
Brian O'Connora84723c2014-06-13 00:26:49 -0700248 return Objects.hash(match, actions);
249 }
250
251 /**
252 * Flow Entries are equal if their matches and action sets are equal.
253 *
254 * @return true if equal, false otherwise
255 */
TeruU30c0c932014-05-15 16:47:41 -0700256 @Override
Ray Milkey269ffb92014-04-03 14:43:30 -0700257 public boolean equals(Object o) {
258 if (!(o instanceof FlowEntry)) {
259 return false;
260 }
261 FlowEntry other = (FlowEntry) o;
262 // Note: we should not consider the operator for this comparison
263 return this.match.equals(other.match)
264 && this.actions.containsAll(other.actions)
265 && other.actions.containsAll(this.actions);
266 }
Brian O'Connor6dc44e92014-02-24 21:23:46 -0800267}