blob: 379426ffcc8015e1deca0e7ca1c1df3463d8aea8 [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 */
Ray Milkey269ffb92014-04-03 14:43:30 -070050 public FlowEntry(long sw, long srcPort, long dstPort,
Brian O'Connorc67f9fa2014-08-07 18:17:46 -070051 MACAddress srcMac, MACAddress dstMac,
52 int srcIpAddress, int dstIpAddress,
53 Operator operator) {
Ray Milkey269ffb92014-04-03 14:43:30 -070054 this.sw = sw;
Komal Shah399a2922014-05-28 01:57:40 -070055 this.match = new Match(sw, srcPort, srcMac, dstMac, srcIpAddress, dstIpAddress);
Ray Milkey269ffb92014-04-03 14:43:30 -070056 this.actions = new HashSet<Action>();
57 this.actions.add(new ForwardAction(dstPort));
58 this.operator = operator;
TeruU9e530662014-05-18 11:49:37 -070059 this.flowEntryId = hashCode();
Ray Milkey269ffb92014-04-03 14:43:30 -070060 }
61
Brian O'Connora84723c2014-06-13 00:26:49 -070062 /**
63 * Gets the switch for this FlowEntry.
64 *
65 * @return the switch's DPID
66 */
67 public long getSwitch() {
68 return sw;
69 }
70
71 /**
72 * Gets the operator (i.e. add, remove, error).
73 *
74 * @return the operator
75 */
76 public Operator getOperator() {
77 return operator;
78 }
79
80 /**
81 * Sets the FlowMod operation (i.e. add, remove, error).
82 *
83 * @param op the operator
84 */
85 public void setOperator(Operator op) {
86 operator = op;
87 }
88
89 /**
TeruU30c0c932014-05-15 16:47:41 -070090 * Gets hard timeout value in seconds.
91 *
TeruU9e530662014-05-18 11:49:37 -070092 * @return the hard timeout value in seconds
TeruU30c0c932014-05-15 16:47:41 -070093 */
94 public int getHardTimeout() {
95 return hardTimeout;
96 }
97
Brian O'Connora84723c2014-06-13 00:26:49 -070098 /**
TeruU30c0c932014-05-15 16:47:41 -070099 * Sets hard timeout value in seconds.
100 *
Sho SHIMIZUa1199fa2014-06-10 18:11:12 -0700101 * @param hardTimeout hard timeout value in seconds
TeruU30c0c932014-05-15 16:47:41 -0700102 */
103 public void setHardTimeout(int hardTimeout) {
104 this.hardTimeout = hardTimeout;
105 }
106
Brian O'Connora84723c2014-06-13 00:26:49 -0700107 /**
108 * Gets idle timeout value in seconds.
109 *
110 * @return the idle timeout value in seconds
111 */
112 public int getIdleTimeout() {
113 return idleTimeout;
114 }
115
116 /**
TeruU30c0c932014-05-15 16:47:41 -0700117 * Sets idle timeout value in seconds.
118 *
Sho SHIMIZUa1199fa2014-06-10 18:11:12 -0700119 * @param idleTimeout idle timeout value in seconds
TeruU30c0c932014-05-15 16:47:41 -0700120 */
121 public void setIdleTimeout(int idleTimeout) {
122 this.idleTimeout = idleTimeout;
123 }
124
Brian O'Connora84723c2014-06-13 00:26:49 -0700125 /**
TeruU9e530662014-05-18 11:49:37 -0700126 * Gets flowEntryId.
127 *
Brian O'Connora84723c2014-06-13 00:26:49 -0700128 * @return the flowEntryId to be set in cookie
TeruU9e530662014-05-18 11:49:37 -0700129 */
130 public long getFlowEntryId() {
131 return flowEntryId;
132 }
133
Brian O'Connora84723c2014-06-13 00:26:49 -0700134 /**
TeruU9e530662014-05-18 11:49:37 -0700135 * Sets flowEntryId.
136 *
Sho SHIMIZUa1199fa2014-06-10 18:11:12 -0700137 * @param flowEntryId flowEntryId to be set in cookie
TeruU9e530662014-05-18 11:49:37 -0700138 */
139 public void setFlowEntryId(long flowEntryId) {
140 this.flowEntryId = flowEntryId;
141 }
142
Brian O'Connora84723c2014-06-13 00:26:49 -0700143 /**
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700144 * Builds and returns an OFFlowMod given an OFFactory.
Brian O'Connora84723c2014-06-13 00:26:49 -0700145 *
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700146 * @param factory the OFFactory to use for building
147 * @return the OFFlowMod
Brian O'Connora84723c2014-06-13 00:26:49 -0700148 */
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700149 public OFFlowMod buildFlowMod(OFFactory factory) {
150 OFFlowMod.Builder builder = null;
151
Ray Milkey269ffb92014-04-03 14:43:30 -0700152 switch (operator) {
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700153 case ADD:
Jonathan Hart3a236002014-08-18 15:23:30 -0700154 // XXX Workaround for semantic differences between OF1.0 and 1.3.
155 // The original code for 1.0 used MODIFY_STRICT but in 1.3 a
156 // MODIFY* command won't create the flow entry if it doesn't
157 // already exist.
158 builder = factory.buildFlowAdd();
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700159 break;
160 case REMOVE:
161 builder = factory.buildFlowDeleteStrict();
162 break;
163 default:
164 // TODO throw error?
165 return null;
Ray Milkey269ffb92014-04-03 14:43:30 -0700166 }
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700167
168 // Build OFMatch
169 Builder matchBuilder = match.getOFMatchBuilder(factory);
170
171 // Build OFAction Set
172 List<OFAction> actionList = new ArrayList<>(actions.size());
173 for (Action action : actions) {
174 actionList.add(action.getOFAction(factory));
175 }
176
177 OFPort outp = OFPort.of((short) 0xffff); // OF1.0 OFPP.NONE
178 if (operator == Operator.REMOVE) {
179 if (actionList.size() == 1) {
180 if (actionList.get(0).getType() == OFActionType.OUTPUT) {
181 OFActionOutput oa = (OFActionOutput) actionList.get(0);
182 outp = oa.getPort();
183 }
184 }
185 }
186
187 // Build OFFlowMod
188 builder.setMatch(matchBuilder.build())
189 .setActions(actionList)
190 .setIdleTimeout(idleTimeout)
191 .setHardTimeout(hardTimeout)
192 .setCookie(U64.of(flowEntryId))
193 .setBufferId(OFBufferId.NO_BUFFER)
194 .setPriority(PRIORITY_DEFAULT)
195 .setOutPort(outp);
196
197 /* Note: The following are NOT USED.
198 * builder.setFlags()
199 * builder.setInstructions()
200 * builder.setOutGroup()
201 * builder.setTableId()
202 * builder.setXid()
203 */
204
205 // TODO from Flow Pusher
206 // Set the OFPFF_SEND_FLOW_REM flag if the Flow Entry is not
207 // permanent.
208 //
209 // if ((flowEntry.idleTimeout() != 0) ||
210 // (flowEntry.hardTimeout() != 0)) {
211 // fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
212 // }
213
214 // TODO do we care?
215 // fm.setOutPort(OFPort.OFPP_NONE.getValue());
216 // if ((flowModCommand == OFFlowMod.OFPFC_DELETE)
217 // || (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
218 // if (actionOutputPort.portNumber != null) {
219 // fm.setOutPort(actionOutputPort.portNumber);
220 // }
221 // }
222
223 // TODO
224 // Set the OFPFF_SEND_FLOW_REM flag if the Flow Entry is not
225 // permanent.
226 //
227 // if ((flowEntry.idleTimeout() != 0) ||
228 // (flowEntry.hardTimeout() != 0)) {
229 // fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
230 // }
231
232 return builder.build();
Ray Milkey269ffb92014-04-03 14:43:30 -0700233 }
234
Brian O'Connora84723c2014-06-13 00:26:49 -0700235 /**
236 * Returns a String representation of this FlowEntry.
237 *
238 * @return the FlowEntry as a String
239 */
TeruU30c0c932014-05-15 16:47:41 -0700240 @Override
Brian O'Connora84723c2014-06-13 00:26:49 -0700241 public String toString() {
242 return match + "->" + actions;
Ray Milkey269ffb92014-04-03 14:43:30 -0700243 }
244
Brian O'Connora84723c2014-06-13 00:26:49 -0700245 /**
246 * Generates hash using Objects.hash() on the match and actions.
247 */
248 @Override
Ray Milkey4373cbe2014-08-12 09:58:58 -0700249 public final int hashCode() {
Brian O'Connora84723c2014-06-13 00:26:49 -0700250 return Objects.hash(match, actions);
251 }
252
253 /**
254 * Flow Entries are equal if their matches and action sets are equal.
255 *
256 * @return true if equal, false otherwise
257 */
TeruU30c0c932014-05-15 16:47:41 -0700258 @Override
Ray Milkey269ffb92014-04-03 14:43:30 -0700259 public boolean equals(Object o) {
260 if (!(o instanceof FlowEntry)) {
261 return false;
262 }
263 FlowEntry other = (FlowEntry) o;
264 // Note: we should not consider the operator for this comparison
265 return this.match.equals(other.match)
266 && this.actions.containsAll(other.actions)
267 && other.actions.containsAll(this.actions);
268 }
Brian O'Connor6dc44e92014-02-24 21:23:46 -0800269}