blob: 53a8c5a0614523a1e9566781e15fdfa4e0b64b01 [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:
154 builder = factory.buildFlowModifyStrict();
155 break;
156 case REMOVE:
157 builder = factory.buildFlowDeleteStrict();
158 break;
159 default:
160 // TODO throw error?
161 return null;
Ray Milkey269ffb92014-04-03 14:43:30 -0700162 }
Brian O'Connorc67f9fa2014-08-07 18:17:46 -0700163
164 // Build OFMatch
165 Builder matchBuilder = match.getOFMatchBuilder(factory);
166
167 // Build OFAction Set
168 List<OFAction> actionList = new ArrayList<>(actions.size());
169 for (Action action : actions) {
170 actionList.add(action.getOFAction(factory));
171 }
172
173 OFPort outp = OFPort.of((short) 0xffff); // OF1.0 OFPP.NONE
174 if (operator == Operator.REMOVE) {
175 if (actionList.size() == 1) {
176 if (actionList.get(0).getType() == OFActionType.OUTPUT) {
177 OFActionOutput oa = (OFActionOutput) actionList.get(0);
178 outp = oa.getPort();
179 }
180 }
181 }
182
183 // Build OFFlowMod
184 builder.setMatch(matchBuilder.build())
185 .setActions(actionList)
186 .setIdleTimeout(idleTimeout)
187 .setHardTimeout(hardTimeout)
188 .setCookie(U64.of(flowEntryId))
189 .setBufferId(OFBufferId.NO_BUFFER)
190 .setPriority(PRIORITY_DEFAULT)
191 .setOutPort(outp);
192
193 /* Note: The following are NOT USED.
194 * builder.setFlags()
195 * builder.setInstructions()
196 * builder.setOutGroup()
197 * builder.setTableId()
198 * builder.setXid()
199 */
200
201 // TODO from Flow Pusher
202 // Set the OFPFF_SEND_FLOW_REM flag if the Flow Entry is not
203 // permanent.
204 //
205 // if ((flowEntry.idleTimeout() != 0) ||
206 // (flowEntry.hardTimeout() != 0)) {
207 // fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
208 // }
209
210 // TODO do we care?
211 // fm.setOutPort(OFPort.OFPP_NONE.getValue());
212 // if ((flowModCommand == OFFlowMod.OFPFC_DELETE)
213 // || (flowModCommand == OFFlowMod.OFPFC_DELETE_STRICT)) {
214 // if (actionOutputPort.portNumber != null) {
215 // fm.setOutPort(actionOutputPort.portNumber);
216 // }
217 // }
218
219 // TODO
220 // Set the OFPFF_SEND_FLOW_REM flag if the Flow Entry is not
221 // permanent.
222 //
223 // if ((flowEntry.idleTimeout() != 0) ||
224 // (flowEntry.hardTimeout() != 0)) {
225 // fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
226 // }
227
228 return builder.build();
Ray Milkey269ffb92014-04-03 14:43:30 -0700229 }
230
Brian O'Connora84723c2014-06-13 00:26:49 -0700231 /**
232 * Returns a String representation of this FlowEntry.
233 *
234 * @return the FlowEntry as a String
235 */
TeruU30c0c932014-05-15 16:47:41 -0700236 @Override
Brian O'Connora84723c2014-06-13 00:26:49 -0700237 public String toString() {
238 return match + "->" + actions;
Ray Milkey269ffb92014-04-03 14:43:30 -0700239 }
240
Brian O'Connora84723c2014-06-13 00:26:49 -0700241 /**
242 * Generates hash using Objects.hash() on the match and actions.
243 */
244 @Override
Ray Milkey4373cbe2014-08-12 09:58:58 -0700245 public final int hashCode() {
Brian O'Connora84723c2014-06-13 00:26:49 -0700246 return Objects.hash(match, actions);
247 }
248
249 /**
250 * Flow Entries are equal if their matches and action sets are equal.
251 *
252 * @return true if equal, false otherwise
253 */
TeruU30c0c932014-05-15 16:47:41 -0700254 @Override
Ray Milkey269ffb92014-04-03 14:43:30 -0700255 public boolean equals(Object o) {
256 if (!(o instanceof FlowEntry)) {
257 return false;
258 }
259 FlowEntry other = (FlowEntry) o;
260 // Note: we should not consider the operator for this comparison
261 return this.match.equals(other.match)
262 && this.actions.containsAll(other.actions)
263 && other.actions.containsAll(this.actions);
264 }
Brian O'Connor6dc44e92014-02-24 21:23:46 -0800265}